Documentation ¶
Overview ¶
Example ¶
The code below puts up a test http server, hits the /example endpoint, decodes the response, prints it, and exits. This is just to exercise the endpoint defined above. The interesting stuff happens above.
package main import ( "encoding/json" "fmt" "io/ioutil" "net/http" "net/http/httptest" "github.com/gorilla/mux" "github.com/muir/nape" ) // The npoint framework distinguishes parameters based on their types. // All parameters of type "string" look the same, but a type that is // defined as another type (like exampleType) is a different type. type ( exampleType string fooParam string fromMiddleware string ) // exampleStaticInjector will not be called until the service.Start() // call in Example_PreregisterServiceWithMux. It will be called only // once per endpoint registered. Since it has a return value, it will // only run if a downstream handler consumes the value it returns. // // The values returned by injectors and available as input parameters // to any downstream handler. func exampleStaticInjector() exampleType { return "example static value" } // exampleInjector will be called for each request. We know that // exampleInjector is a regular injector because it takes a parameter // that is specific to the request (*http.Request). func exampleInjector(r *http.Request) fooParam { return fooParam(r.FormValue("foo")) } type returnValue interface{} // jsonifyResult wraps all handlers downstream of it in the call chain. // We know that jsonifyResult is a middleware handler because its first // argument is an function with an anonymous type (inner). Calling inner // invokes all handlers downstream from jsonifyResult. The value returned // by inner can come from the return values of the final endpoint handler // or from values returned by any downstream middleware. The parameters // to inner are available as inputs to any downstream handler. // // Parameters are matched by their types. Since inner returns a returnValue, // it can come from any downstream middleware or endpoint that returns something // of type returnValue. func jsonifyResult(inner func(fromMiddleware) returnValue, w http.ResponseWriter) { v := inner("jsonify!") w.Header().Set("Content-Type", "application/json") encoded, _ := json.Marshal(v) w.WriteHeader(200) _, _ = w.Write(encoded) } // Endpoints are grouped and started by services. Handlers that are // common to all endpoints are attached to the service. var service = nape.PreregisterServiceWithMux("example-service", exampleStaticInjector, jsonifyResult) func init() { // The /example endpoint is bound to a handler chain // that combines the functions included at the service // level and the functions included here. The final chain is: // exampleStaticInjector, jsonifyResult, exampleInjector, exampleEndpoint. // ExampleStaticInjector and jsonifyResult come from the service // definition. ExampleInjector and exampleEndpoint are attached when // the endpoint is registered. // // Handlers will execute in the order of the chain: exampleStaticInjector // then jsonifyResult. When jsonifyResult calls inner(), exampleInjector // runs, then exampleEndpoint. When exampleEndpoint returns, inner() returns // so jsonifyResult continues its work. When jsonifyResult returns, the // handler chain is complete and the http server can form a reply from the // ResponseWriter. // // Since service is WithMux, we can use gorilla mux modifiers when // we register endpoints. This allows us to trivially indicate that our // example endpoint supports the GET method only. service.RegisterEndpoint( "/example", exampleInjector, exampleEndpoint).Methods("GET") } // This is the final endpoint handler. The parameters it takes can // be provided by any handler upstream from it. It can also take the two // values that are included by the http handler signature: http.ResponseWriter // and *http.Request. // // Any values that the final endpoint handler returns must be consumed by an // upstream middleware handler. In this example, a "returnValue" is returned // here and consumed by jsonifyResult. func exampleEndpoint(sv exampleType, foo fooParam, mid fromMiddleware) returnValue { return map[string]string{ "value": fmt.Sprintf("%s-%s-%s", sv, foo, mid), } } // The code below puts up a test http server, hits the /example // endpoint, decodes the response, prints it, and exits. This // is just to exercise the endpoint defined above. The interesting // stuff happens above. func main() { muxRouter := mux.NewRouter() service.Start(muxRouter) localServer := httptest.NewServer(muxRouter) defer localServer.Close() // nolint:noctx r, err := http.Get(localServer.URL + "/example?foo=bar") if err != nil { fmt.Println("get error", err) return } buf, err := ioutil.ReadAll(r.Body) if err != nil { fmt.Println("read error", err) return } r.Body.Close() var res map[string]string err = json.Unmarshal(buf, &res) if err != nil { fmt.Println("unmarshal error", err) return } fmt.Println("Value:", res["value"]) }
Output: Value: example static value-bar-jsonify!
Index ¶
- Variables
- type EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) BuildOnly() *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) BuildVarsFunc(f mux.BuildVarsFunc) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) GetError() error
- func (r *EndpointRegistrationWithMux) GetHandler() http.Handler
- func (r *EndpointRegistrationWithMux) GetHostTemplate() (string, error)
- func (r *EndpointRegistrationWithMux) GetName() string
- func (r *EndpointRegistrationWithMux) GetPathTemplate() (string, error)
- func (r *EndpointRegistrationWithMux) Headers(pairs ...string) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) HeadersRegexp(pairs ...string) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) Host(tpl string) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) Match(req *http.Request, match *mux.RouteMatch) bool
- func (r *EndpointRegistrationWithMux) MatcherFunc(f mux.MatcherFunc) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) Methods(methods ...string) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) Name(name string) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) Path(tpl string) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) PathPrefix(tpl string) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) Queries(pairs ...string) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) Route() (*mux.Route, error)
- func (r *EndpointRegistrationWithMux) Schemes(schemes ...string) *EndpointRegistrationWithMux
- func (r *EndpointRegistrationWithMux) SkipClean() bool
- func (r *EndpointRegistrationWithMux) URL(pairs ...string) (*url.URL, error)
- func (r *EndpointRegistrationWithMux) URLHost(pairs ...string) (*url.URL, error)
- func (r *EndpointRegistrationWithMux) URLPath(pairs ...string) (*url.URL, error)
- type ServiceRegistrationWithMux
- type ServiceWithMux
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DecodeJSON = nvelope.GenerateDecoder( nvelope.WithDecoder("application/json", json.Unmarshal), nvelope.WithDefaultContentType("application/json"), nvelope.WithPathVarsFunction(func(r *http.Request) nvelope.RouteVarLookup { vars := mux.Vars(r) return func(v string) string { return vars[v] } }), )
DecodeJSON is is a pre-defined special nject.Provider created with nvelope.GenerateDecoder for decoding JSON requests. Use it with the other features of https://github.com/muir/nvelope
var DecodeXML = nvelope.GenerateDecoder( nvelope.WithDecoder("application/xml", xml.Unmarshal), nvelope.WithDefaultContentType("application/xml"), nvelope.WithPathVarsFunction(func(r *http.Request) nvelope.RouteVarLookup { vars := mux.Vars(r) return func(v string) string { return vars[v] } }), )
DecodeXML is is a pre-defined special nject.Provider created with nvelope.GenerateDecoder for decoding XML requests.Use it with the other features of https://github.com/muir/nvelope
Functions ¶
This section is empty.
Types ¶
type EndpointRegistrationWithMux ¶
type EndpointRegistrationWithMux struct {
// contains filtered or unexported fields
}
EndpointRegistrationWithMux holds endpoint definitions for services that will be Start()ed with gorilla mux. Most of the gorilla mux methods can be used with these endpoint definitions.
func (*EndpointRegistrationWithMux) BuildOnly ¶
func (r *EndpointRegistrationWithMux) BuildOnly() *EndpointRegistrationWithMux
BuildOnly applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) BuildVarsFunc ¶
func (r *EndpointRegistrationWithMux) BuildVarsFunc(f mux.BuildVarsFunc) *EndpointRegistrationWithMux
BuildVarsFunc applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) GetError ¶
func (r *EndpointRegistrationWithMux) GetError() error
GetError calls the mux.Route method of the same name on the route created for this endpoint.
func (*EndpointRegistrationWithMux) GetHandler ¶
func (r *EndpointRegistrationWithMux) GetHandler() http.Handler
GetHandler calls the mux.Route method of the same name on the route created for this endpoint.
func (*EndpointRegistrationWithMux) GetHostTemplate ¶
func (r *EndpointRegistrationWithMux) GetHostTemplate() (string, error)
GetHostTemplate calls the mux.Route method of the same name on the route created for this endpoint.
func (*EndpointRegistrationWithMux) GetName ¶
func (r *EndpointRegistrationWithMux) GetName() string
GetName calls the mux.Route method of the same name on the route created for this endpoint.
func (*EndpointRegistrationWithMux) GetPathTemplate ¶
func (r *EndpointRegistrationWithMux) GetPathTemplate() (string, error)
GetPathTemplate calls the mux.Route method of the same name on the route created for this endpoint.
func (*EndpointRegistrationWithMux) Headers ¶
func (r *EndpointRegistrationWithMux) Headers(pairs ...string) *EndpointRegistrationWithMux
Headers applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) HeadersRegexp ¶
func (r *EndpointRegistrationWithMux) HeadersRegexp(pairs ...string) *EndpointRegistrationWithMux
HeadersRegexp applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) Host ¶
func (r *EndpointRegistrationWithMux) Host(tpl string) *EndpointRegistrationWithMux
Host applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) Match ¶
func (r *EndpointRegistrationWithMux) Match(req *http.Request, match *mux.RouteMatch) bool
Match calls the mux.Route method of the same name on the route created for this endpoint.
func (*EndpointRegistrationWithMux) MatcherFunc ¶
func (r *EndpointRegistrationWithMux) MatcherFunc(f mux.MatcherFunc) *EndpointRegistrationWithMux
MatcherFunc applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) Methods ¶
func (r *EndpointRegistrationWithMux) Methods(methods ...string) *EndpointRegistrationWithMux
Methods applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) Name ¶
func (r *EndpointRegistrationWithMux) Name(name string) *EndpointRegistrationWithMux
Name applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) Path ¶
func (r *EndpointRegistrationWithMux) Path(tpl string) *EndpointRegistrationWithMux
Path applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) PathPrefix ¶
func (r *EndpointRegistrationWithMux) PathPrefix(tpl string) *EndpointRegistrationWithMux
PathPrefix applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) Queries ¶
func (r *EndpointRegistrationWithMux) Queries(pairs ...string) *EndpointRegistrationWithMux
Queries applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) Route ¶
func (r *EndpointRegistrationWithMux) Route() (*mux.Route, error)
Route returns the *mux.Route that has been registered to this endpoint, if possible.
func (*EndpointRegistrationWithMux) Schemes ¶
func (r *EndpointRegistrationWithMux) Schemes(schemes ...string) *EndpointRegistrationWithMux
Schemes applies the mux.Route method of the same name to this endpoint when the endpoint is initialized.
func (*EndpointRegistrationWithMux) SkipClean ¶
func (r *EndpointRegistrationWithMux) SkipClean() bool
SkipClean calls the mux.Route method of the same name on the route created for this endpoint.
func (*EndpointRegistrationWithMux) URL ¶
func (r *EndpointRegistrationWithMux) URL(pairs ...string) (*url.URL, error)
URL calls the mux.Route method of the same name on the route created for this endpoint.
type ServiceRegistrationWithMux ¶
type ServiceRegistrationWithMux struct { Name string Collection *nject.Collection // contains filtered or unexported fields }
ServiceRegistrationWithMux allows a group of related endpoints to be started together. This form of service represents pre-registered service service that binds its endpoints using gorilla mux.Router.HandleFunc. None of the endpoints associated with this service will initialize themselves or start listening until Start() is called.
func PreregisterServiceWithMux ¶
func PreregisterServiceWithMux(name string, funcs ...interface{}) *ServiceRegistrationWithMux
PreregisterServiceWithMux creates a service that must be Start()ed later.
The passed in funcs follow the same rules as for the funcs in a nject.Collection.
The injectors and middlware functions will precede any injectors and middleware specified on each endpoint that registers with this service.
PreregsteredServices do not initialize or bind to handlers until they are Start()ed.
The name of the service is just used for error messages and is otherwise ignored.
func (*ServiceRegistrationWithMux) RegisterEndpoint ¶
func (s *ServiceRegistrationWithMux) RegisterEndpoint(path string, funcs ...interface{}) *EndpointRegistrationWithMux
RegisterEndpoint pre-registers an endpoint. The provided funcs must all match one of the handler types. The functions provided are invoked in-order. Static injectors first and the endpoint last.
The return value does not need to be retained -- it is also remembered in the Service. The return value can be used to add mux.Route-like modifiers. They will not take effect until the service is started.
The endpoint initialization will not run until the service is started. If the service has already been started, the endpoint will be started immediately.
func (*ServiceRegistrationWithMux) Start ¶
func (s *ServiceRegistrationWithMux) Start(router *mux.Router) *ServiceWithMux
Start calls endpoints initializers for this Service and then registers all the endpoint handlers to the router. Start() should be called at most once.
type ServiceWithMux ¶
type ServiceWithMux struct { Name string Collection *nject.Collection // contains filtered or unexported fields }
ServiceWithMux allows a group of related endpoints to be started together. This form of service represents an already-started service that binds its endpoints using gorilla mux.Router.HandleFunc.
func RegisterServiceWithMux ¶
func RegisterServiceWithMux(name string, router *mux.Router, funcs ...interface{}) *ServiceWithMux
RegisterServiceWithMux creates a service and starts it immediately.
func (*ServiceWithMux) RegisterEndpoint ¶
func (s *ServiceWithMux) RegisterEndpoint(path string, funcs ...interface{}) *mux.Route
RegisterEndpoint registers and immediately starts an endpoint. The provided funcs must all match one of the handler types. The functions provided are invoked in-order. Static injectors first and the endpoint last.