crpc

package
v0.0.0-...-4eb781d Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2024 License: MIT Imports: 24 Imported by: 2

README

crpc

crpc contains a client and server conforming to the Cuvva RPC standard.

It is heavily influenced by net/rpc and Monzo Typhon.

Components

crpc consists of a Client and a Server component.

Client

The Client component is not intended to be used directly, but to be composed into a more fully-featured service client.

See example/client/ for example usage.

Server

The Server component is intended to be used directly, and have handlers associated directly with it.

It implements net/http.Handler, thus can be embedded directly within an HTTP server. This is in preparation of enabling TLS between service, and thus internal RPC can use HTTP/2 multiplexing.

See example/server/ for example usage.

Documentation

Index

Constants

View Source
const (
	// VersionPreview is used for experimental endpoints in development which
	// are coming but a version identifier has not been decided yet or may
	// be withdrawn at any point.
	VersionPreview = "preview"

	// VersionLatest is used by engineers only to call the latest version
	// of an endpoint in utilities like cURL and Paw.
	VersionLatest = "latest"
)
View Source
const (
	// CuvvaEndpointStatus is the header appended to the response indicating the
	// usability status of the endpoint.
	CuvvaEndpointStatus = `Cuvva-Endpoint-Status`

	// PreviewNotice is the contents of the `Cuvva-Endpoint-Status` header when an
	// endpoint is called with the preview version.
	PreviewNotice = `preview; msg="endpoint is experimental and may change/be withdrawn without notice"`

	// LatestNotice is the contents of the `Cuvva-Endpoint-Status` header when an
	// endpoint is called to request the latest version.
	LatestNotice = `latest; msg="subject to change without notice"`

	// StableNotice is the contents of the `Cuvva-Endpoint-Status` header when an
	// endpoint is called and is not expected to change.
	StableNotice = `stable`
)

Variables

This section is empty.

Functions

func CoerceJSONSchemaError

func CoerceJSONSchemaError(result *gojsonschema.Result) error

func Instrument

func Instrument(r prometheus.Registerer) func(HandlerFunc) HandlerFunc

Instrument adds prometheus compatible metrics collection to RPC functions. The metrics collected are:

  • duration
  • status code
  • total in-flight

func NoLongerSupported

func NoLongerSupported(_ http.ResponseWriter, _ *Request) error

NoLongerSupported is a HandlerFunc which always returns the error `no_longer_supported` to the requester to indicate methods which have been withdrawn.

func RequireMinimumClientVersions

func RequireMinimumClientVersions(requirements ...VersionRequirement) func(HandlerFunc) HandlerFunc

RequireMinimumClientVersions will return an error to the client if: - the reqest has a valid client version header, and - the platform matches but the semver requirement is greater than the client semver

Types

type Client

type Client struct {
	*jsonclient.Client
}

Client represents a crpc client. It builds on top of jsonclient, so error variables/structs and the authenticated round tripper live there.

func NewClient

func NewClient(ctx context.Context, baseURL string, c *http.Client) *Client

NewClient returns a client configured with a transport scheme, remote host and URL prefix supplied as a URL <scheme>://<host></prefix>

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, version string, src, dst interface{}) error

Do executes an RPC request against the configured server.

func (*Client) WithUASuffix

func (c *Client) WithUASuffix(suffix string) *Client

WithUASuffix updates the current user agent with an additional string

type ClientTransportError

type ClientTransportError struct {
	Method, Version, ErrorString string
	// contains filtered or unexported fields
}

ClientTransportError is returned when an error related to executing a client request occurs.

func (*ClientTransportError) Cause

func (cte *ClientTransportError) Cause() error

Cause returns the causal error (if wrapped) or nil

func (*ClientTransportError) Error

func (cte *ClientTransportError) Error() string

type HandlerFunc

type HandlerFunc func(res http.ResponseWriter, req *Request) error

HandlerFunc defines a handler for an RPC request. Request and response body data will be JSON. Request will immediately io.EOF if there is no request.

type MiddlewareFunc

type MiddlewareFunc func(next HandlerFunc) HandlerFunc

MiddlewareFunc is a function that wraps HandlerFuncs.

func Logger

func Logger() MiddlewareFunc

Logger inherits the context logger and reports RPC request success/failure.

func Validate

func Validate(ls *gojsonschema.Schema) MiddlewareFunc

Validate buffers the JSON body and applies a JSON Schema validation.

type Request

type Request struct {
	Version string
	Method  string

	Body io.ReadCloser

	RemoteAddr    string
	BrowserOrigin string
	// contains filtered or unexported fields
}

Request contains metadata about the RPC request.

func GetRequestContext

func GetRequestContext(ctx context.Context) *Request

GetRequestContext returns the Request from the context object

func (*Request) Context

func (r *Request) Context() context.Context

Context returns the requests context from the transport.

The returned context is always non-nil, it defaults to the background context.

func (*Request) WithContext

func (r *Request) WithContext(ctx context.Context) *Request

WithContext sets the context of a Request

type ResponseWriter

type ResponseWriter interface {
	io.Writer
}

ResponseWriter is the destination for RPC responses.

type Server

type Server struct {
	// AuthenticationMiddleware applies authentication before any other
	// middleware or request is processed. Servers without middleware must
	// configure the UnsafeNoAuthentication middleware. If no
	// AuthenticationMiddleware is configured, the server will panic.
	AuthenticationMiddleware MiddlewareFunc
	// contains filtered or unexported fields
}

Server is an HTTP-compatible crpc handler.

func NewServer

func NewServer(auth MiddlewareFunc) *Server

NewServer returns a new RPC Server with an optional exception tracker.

func (*Server) Register

func (s *Server) Register(method, version string, schema gojsonschema.JSONLoader, fnR interface{}, mw ...MiddlewareFunc)

Register reflects a HandlerFunc from fnR and associates it with a method name and version. If fnR does not meet the HandlerFunc standard defined above, or the presence of the schema doesn't match the presence of the input argument, Register will panic. This function is not thread safe and must be run in serial if called multiple times.

func (*Server) RegisterFunc

func (s *Server) RegisterFunc(method, version string, schema gojsonschema.JSONLoader, fn *HandlerFunc, mw ...MiddlewareFunc)

RegisterFunc associates a method name and version with a HandlerFunc, and optional middleware. This function is not thread safe and must be run in serial if called multiple times.

func (*Server) Serve

func (s *Server) Serve(res http.ResponseWriter, req *Request) error

Serve executes an RPC request.

func (*Server) ServeHTTP

func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

func (*Server) Use

func (s *Server) Use(mw MiddlewareFunc)

Use includes a piece of Middleware to wrap HandlerFuncs.

type VersionRequirement

type VersionRequirement struct {
	Platform string
	Version  semver.Version
}

VersionRequirement is our predicate type for checking client versions

func NewVersionRequirement

func NewVersionRequirement(platform string, ver semver.Version) VersionRequirement

NewVersionRequirement creates a predicate for evaluation e.g. IF platform is "ios" THEN the minimum version allowed is "3.6.8"

type WrappedFunc

type WrappedFunc struct {
	Handler       HandlerFunc
	AcceptsInput  bool
	ReturnsResult bool
}

WrappedFunc contains the wrapped handler, and some additional information about the function that was determined during the reflection process

func MustWrap

func MustWrap(fn interface{}) *WrappedFunc

MustWrap is the same as Wrap, however it panics when passed an invalid handler.

func Wrap

func Wrap(fn interface{}) (*WrappedFunc, error)

Wrap reflects a HandlerFunc from any function matching the following signatures:

func(ctx context.Context, request *T) (response *T, err error) func(ctx context.Context, request *T) (err error) func(ctx context.Context) (response *T, err error) func(ctx context.Context) (err error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL