rpc

package
v1.1.5 Latest Latest
Warning

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

Go to latest
Published: May 24, 2023 License: MIT Imports: 20 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Binder

type Binder interface {
	Bind(req *http.Request, out interface{}) error
}

Binder performs the work of taking all meaningful values from an incoming request (body, path params, query string) and applying them to a Go struct (likely the "XxxRequest" for your service method).

type Client

type Client struct {
	// HTTP takes care of the raw HTTP request/response logic used when communicating w/ remote services.
	HTTP *http.Client
	// BaseURL contains the protocol/host/port/etc that is the prefix for all service function
	// endpoints. (e.g. "http://api.myawesomeapp.com")
	BaseURL string
	// PathPrefix sits between the host/port and the endpoint path (e.g. something like "v2") so that
	// you can segment/version your services. Typically this will be the same as what you apply as
	// the gateway's path prefix.
	PathPrefix string
	// Name is just the display name of the service; used only for debugging/tracing purposes.
	Name string
	// contains filtered or unexported fields
}

Client manages all RPC communication with other frodo-powered services. It uses HTTP under the hood, so you can supply a custom HTTP client by including WithHTTPClient() when calling your client constructor, NewXxxServiceClient().

func NewClient

func NewClient(name string, addr string, options ...ClientOption) Client

NewClient constructs the RPC client that does the "heavy lifting" when communicating with remote frodo-powered RPC services. It contains all data/logic required to marshal/unmarshal requests/responses as well as communicate w/ the remote service.

func (Client) Invoke

func (c Client) Invoke(ctx context.Context, method string, path string, serviceRequest interface{}, serviceResponse interface{}) error

Invoke handles the standard request/response logic used to call a service method on the remote service. You should NOT call this yourself. Instead, you should stick to the strongly typed, code-generated service functions on your client.

type ClientMiddlewareFunc

type ClientMiddlewareFunc func(request *http.Request, next RoundTripperFunc) (*http.Response, error)

ClientMiddlewareFunc is a round-tripper-like function that accepts a request and returns a response/error combo, but also accepts 'next' (the rest of the computation) so that you can short circuit the execution as you see fit.

type ClientOption

type ClientOption func(*Client)

ClientOption is a single configurable setting that modifies some attribute of the RPC client when building one via NewClient().

func WithClientMiddleware

func WithClientMiddleware(funcs ...ClientMiddlewareFunc) ClientOption

WithClientMiddleware sets the chain of HTTP request/response handlers you want to invoke on each service function invocation before/after we dispatch the HTTP request.

func WithHTTPClient

func WithHTTPClient(httpClient *http.Client) ClientOption

WithHTTPClient allows you to provide an HTTP client configured to your liking. You do not *need* to supply this. The default client already implements a 30 second timeout, but if you want a different timeout or custom dialer/transport/etc, then you can feed in you custom client here and we'll use that one for all HTTP communication with other services.

type CompositeGateway

type CompositeGateway struct {
	// Name is a colon-separated string containing the names of all of the services wrapped up in here.
	Name string
	// Gateways tracks all of the original gateways that this is wrapping up.
	Gateways []Gateway
	// Router is the HTTP mux that does the actual request routing work.
	Router *httptreemux.TreeMux
	// contains filtered or unexported fields
}

CompositeGateway is a gateway that is composed of multiple service RPC Gateway instances. You use one of these when you want to run multiple services in the same process (like for local dev).

func Compose

func Compose(gateways ...Gateway) CompositeGateway

Compose accepts multiple gateways generated using the 'frodo' tool in order to allow them to run in the same HTTP server/listener. A typical use-case for this functionality is when you are running microservices in local development. Rather than starting/stopping 20 different processes, you can run all of your services in a single server process:

userGateway := users.NewUserServiceGateway(userService)
groupGateway := groups.NewGroupServiceGateway(groupService)
projectGateway := projects.NewProjectServiceGateway(projectService)

gateway := rpc.Compose(
    userGateway,
    groupGateway,
    projectGateway,
)
http.listenAndService(":8080", gateway)

This will preserve all of the original gateways as well. Now you'll just have a "master" gateway that contains all of the routes/endpoints from all of the services.

func (CompositeGateway) ServeHTTP

func (gw CompositeGateway) ServeHTTP(w http.ResponseWriter, req *http.Request)

type ContentFileNameReader

type ContentFileNameReader respond.ContentFileNameReader

ContentFileNameReader allows raw responses to specify the file name (if any) of the file the bytes represent.

type ContentFileNameWriter

type ContentFileNameWriter interface {
	// SetContentFileName applies the file name value data to the response.
	SetContentFileName(contentFileName string)
}

ContentFileNameWriter allows raw responses to specify the file name (if any) of the file the bytes represent. This is utilized by clients to automatically populate content type values received from the gateway.

type ContentReader

type ContentReader respond.ContentReader

ContentReader defines a response type that should be treated as raw bytes, not JSON.

type ContentTypeReader

type ContentTypeReader respond.ContentTypeReader

ContentTypeReader allows raw responses to specify what type of data the bytes represent.

type ContentTypeWriter

type ContentTypeWriter interface {
	// SetContentType applies the content type value data to the response.
	SetContentType(contentType string)
}

ContentTypeWriter allows raw responses to specify what type of data the bytes represent. This is utilized by clients to automatically populate content type values received from the gateway.

type ContentWriter

type ContentWriter interface {
	// SetContent applies the raw byte data to the response.
	SetContent(reader io.ReadCloser)
}

ContentWriter defines a response type that should be treated as raw bytes, not JSON. This is utilized by clients to automatically populate readers received from the gateway.

type Endpoint

type Endpoint struct {
	// The HTTP method that should be used when exposing this endpoint in the gateway.
	Method string
	// The HTTP path pattern that should be used when exposing this endpoint in the gateway.
	Path string
	// ServiceName is the name of the service that this operation is part of.
	ServiceName string
	// Name is the name of the function/operation that this endpoint describes.
	Name string
	// Handler is the gateway function that does the "work".
	Handler http.HandlerFunc
}

Endpoint describes an operation that we expose through an RPC gateway.

func EndpointFromContext

func EndpointFromContext(ctx context.Context) *Endpoint

EndpointFromContext fetches the meta information about the service RPC operation that we're currently invoking.

func (Endpoint) String

func (e Endpoint) String() string

String just returns the fully qualified "Service.Operation" descriptor for the operation.

type Gateway

type Gateway struct {
	Name   string
	Router *httptreemux.TreeMux

	Binder     Binder
	PathPrefix string
	// contains filtered or unexported fields
}

Gateway wrangles all of the incoming RPC/HTTP handling for your service calls. It automatically converts all transport data into your Go request struct. Conversely, it also marshals and transmits your service response struct data back to the caller. Aside from feeding this to `http.ListenAndServe()` you likely won't interact with this at all yourself.

func NewGateway

func NewGateway(options ...GatewayOption) Gateway

NewGateway creates a wrapper around your raw service to expose it via HTTP for RPC calls.

func (*Gateway) Register

func (gw *Gateway) Register(endpoint Endpoint)

Register the operation with the gateway so that it can be exposed for invoking remotely.

func (Gateway) ServeHTTP

func (gw Gateway) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP is the central HTTP handler that includes all http routing, middleware, service forwarding, etc.

type GatewayOption

type GatewayOption func(*Gateway)

GatewayOption defines a setting you can apply when creating an RPC gateway via 'NewGateway'.

func WithBinder

func WithBinder(binder Binder) GatewayOption

WithBinder allows you to override a Gateway's default binding behavior with the custom behavior of your choice.

func WithMiddleware

func WithMiddleware(mw ...MiddlewareFunc) GatewayOption

WithMiddleware invokes this chain of work before executing the actual HTTP handler for your service call. Any functions yu supply here will fire before your service function, but after built-in middleware functions such as the one that restores metadata (i.e. your middleware will have access to request/context metadata).

func WithNotFoundMiddleware

func WithNotFoundMiddleware(handlers ...MiddlewareFunc) GatewayOption

WithNotFoundMiddleware registers a custom handler with the internal RPC/HTTP router that lets you assign custom behaviors/handling for requests that do not map to any of your service functions. This will perform handling for both 404-style Not Found errors AND 405-style Method Not Allowed errors.

You'll notice that this accepts a MiddlewareFunc rather than a standard HTTP handler func. The reason is that 99% of the time you don't want to change the behavior of 404/405 handling - you just want to inject some logging, metrics, etc. Since you likely have middleware for those things already, you can just re-use them as needed and then delegate to "next()" to finish the standard response handling (status code, Allow headers, etc.).

If you really do want to provide custom handling such as returning an HTTP 200 if the path is "/health" or something like that, you can short circuit the standard handler by simply not calling "next()", just as you would with standard middleware.

type MiddlewareFunc

type MiddlewareFunc func(w http.ResponseWriter, req *http.Request, next http.HandlerFunc)

MiddlewareFunc is a component that conforms to the 'negroni' middleware function. It accepts the standard HTTP inputs as well as the rest of the computation.

func (MiddlewareFunc) ServeHTTP

func (mw MiddlewareFunc) ServeHTTP(w http.ResponseWriter, req *http.Request, next http.HandlerFunc)

ServeHTTP basically calls itself. This is a mechanism that lets middleware functions be passed around the same as a full middleware handler component.

type RoundTripperFunc

type RoundTripperFunc func(r *http.Request) (*http.Response, error)

RoundTripperFunc matches the signature of the standard http.RoundTripper interface.

func (RoundTripperFunc) RoundTrip

func (rt RoundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip allows a single round trip function to behave as a full-fledged http.RoundTripper.

Directories

Path Synopsis
Package errors provides a curated list of standard types of failures you'll likely encounter when executing RPC handlers.
Package errors provides a curated list of standard types of failures you'll likely encounter when executing RPC handlers.
Package metadata provides request-scoped values for your RPC calls.
Package metadata provides request-scoped values for your RPC calls.

Jump to

Keyboard shortcuts

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