Documentation ¶
Overview ¶
Package hyperdrive is an opinonated micro-framework for writing hypermedia APIs. It attempts to embrace the best of Hypermedia, especially the separation of client and server, encapsulated in the principle of HATEOAS (HTTP as the Engine of Application State).
Hyperdrive APIs are resource-oriented, make heavy use of `http.Handler` middleware patterns, and takes advantage of HTTP verbs, headers, and other transport specific features, as much as possible. Other than that, it assumes nothing about how you store and retrieve your endpoint's hypermedia respresentations.
Index ¶
- func BodyParams(r *http.Request) url.Values
- func GetContentTypeJSON(api API, e Endpointer) string
- func GetContentTypeXML(api API, e Endpointer) string
- func GetContentTypes(api API, e Endpointer) []string
- func GetContentTypesList(api API, e Endpointer) string
- func GetErrorText(status int, err error) string
- func GetMediaType(api API, e Endpointer) string
- func GetMethods(e Endpointer) []string
- func GetMethodsList(e Endpointer) string
- func GetParams(e Endpointer, r *http.Request) (url.Values, error)
- func NewMethodHandler(e Endpointer) http.Handler
- func Params(r *http.Request) url.Values
- func PathParams(r *http.Request) url.Values
- func QueryParams(r *http.Request) url.Values
- func Respond(rw http.ResponseWriter, r *http.Request, status int, body interface{}, ...) (http.ResponseWriter, *http.Request)
- type API
- func (api *API) AddEndpoint(e Endpointer)
- func (api *API) CompressionMiddleware(h http.Handler) http.Handler
- func (api *API) ContentTypeOptionsMiddleware(h http.Handler) http.Handler
- func (api *API) CorsMiddleware(h http.Handler) http.Handler
- func (api *API) DefaultMiddlewareChain(h http.Handler) http.Handler
- func (api *API) FrameOptionsMiddleware(h http.Handler) http.Handler
- func (api *API) LoggingMiddleware(h http.Handler) http.Handler
- func (api *API) MethodOverrideMiddleware(h http.Handler) http.Handler
- func (api *API) RecoveryMiddleware(h http.Handler) http.Handler
- func (api *API) Start()
- type Config
- type ContentEncoder
- type DeleteHandler
- type Endpoint
- type EndpointResource
- type EndpointResourceParam
- type Endpointer
- type GetHandler
- type JSONEncoder
- type NullEncoder
- type OptionsHandler
- type Parameter
- type PatchHandler
- type PostHandler
- type PutHandler
- type RootResource
- type XMLEncoder
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BodyParams ¶ added in v0.0.5
BodyParams deserializes the input, and extracts the values from the request body. It returns a url.Values object (essentially map[string][]string). If the request method is GET, an empty url.Values is returned.
func GetContentTypeJSON ¶ added in v0.0.4
func GetContentTypeJSON(api API, e Endpointer) string
GetContentTypeJSON returns the json Content-Type an endpoint can accept and respond with. The Content-Type will include the versioned vendor Media Type returned by API.GetMediaType() with a json extension.
func GetContentTypeXML ¶ added in v0.0.4
func GetContentTypeXML(api API, e Endpointer) string
GetContentTypeXML returns the xml Content-Type an endpoint can accept and respond with. The Content-Type will include the versioned vendor Media Type returned by API.GetMediaType() with an xml extension.
func GetContentTypes ¶ added in v0.0.4
func GetContentTypes(api API, e Endpointer) []string
GetContentTypes returns a slice of Content-Types that the endpoint can accept and respond with. The Content-Types will include both the versioned vendor Media Type returned by API.GetMediaType() for both json and xml.
func GetContentTypesList ¶ added in v0.0.4
func GetContentTypesList(api API, e Endpointer) string
GetContentTypesList returns a list of Content-Type strings that the endpoint can accept and respond with. The Content-Types will include both the versioned vendor Media Type returned by API.GetMediaType() for both json and xml.
func GetErrorText ¶ added in v0.0.4
GetErrorText helps ensure implementation details are not leaked in production environments. If this is production, it returns the http.StatusText for the given status code. If this is not production, the error message is returned to aid in debugging.
func GetMediaType ¶ added in v0.0.4
func GetMediaType(api API, e Endpointer) string
GetMediaType returns a media type string, sans any content-type extension (e.g. json), based on the name of the API, the Endpoint, and the Endpoint's version. The Media Type produced will be used for Content Negotiation, via the Accept header, as well as routing to the appropriate endpoint, when the media type appears in the request headers (e.g. Accept and Content-Type). It will also be used, after content negotiation in the Content-Type response header.
func GetMethods ¶ added in v0.0.3
func GetMethods(e Endpointer) []string
GetMethods returns a slice of the methods an Endpoint supports.
func GetMethodsList ¶ added in v0.0.3
func GetMethodsList(e Endpointer) string
GetMethodsList returns a list of the methods an Endpoint supports.
func GetParams ¶ added in v0.0.5
GetParams returns all allowed request params. It returns an error on the first required param is not present. GetParams is intended to be used in your method handlers in a given endpoint.
func NewMethodHandler ¶ added in v0.0.3
func NewMethodHandler(e Endpointer) http.Handler
NewMethodHandler sets the correct http.Handler for each method, depending on the interfaces the Endpointer supports. It returns an http.Handler, ready to be served directly, wrapped in other middleware, etc.
func Params ¶ added in v0.0.5
Params extracts the param values from all sources: query, body, and path -- in that order. Each subsequent source will overwrite values with the same key, to ensure API client intent is maintained in a consistent way.
func PathParams ¶ added in v0.0.5
PathParams extracts the values from the request path which match named params in the route. They are returned as url.Values for consistincey with http.Request.Form's behaviour.
func QueryParams ¶ added in v0.0.5
QueryParams extracts the values from the request QueryString. It returns a url.Values object (essentially map[string][]string). If the request method is not GET, an empty url.Values is returned.
func Respond ¶ added in v0.0.4
func Respond(rw http.ResponseWriter, r *http.Request, status int, body interface{}, headers ...http.Header) (http.ResponseWriter, *http.Request)
Respond is a helper function to make it easy for an Endpointer's method handler (e.g. GetHandler) to respond with the appropriate Content-Type.
Types ¶
type API ¶
type API struct { Name string Desc string Router *mux.Router Server *http.Server Root *RootResource // contains filtered or unexported fields }
API is a logical collection of one or more endpoints, connecting requests to the response handlers using a gorlla mux Router.
func NewAPI ¶
NewAPI creates an instance of API, with an initialized Router, Config, Server, and RootResource.
func (*API) AddEndpoint ¶
func (api *API) AddEndpoint(e Endpointer)
AddEndpoint registers endpoints, ensuring that endpoints automatically respond with a 405 error if the endpoint does not support a particular HTTP method.
func (*API) CompressionMiddleware ¶ added in v0.0.3
CompressionMiddleware wraps the given http.Handler and returns a gzipped response if the client requests it with the Accept-Encoding header. The compression level is set to to 1, by default. You can configure this though the GZIP_LEVEL environment variable, and set it to an integer between -2 and 9.
Following zlib, levels range from 1 (Best Speed) to 9 (Best Compression); higher levels typically run slower but compress more.
-1 is the Default Compression level, and is also used if an invalid value is configured via GZIP_LEVEL.
0 attempts no compression, and only adds the necessary DEFLATE framing.
-2 disables Lempel-Ziv match searching and only performs Huffman entropy encoding. This is useful when compressing data that has already been compressed with an LZ style algorithm, such as Snappy or LZ4.
More info can be found in the docs for the compress/flate package: https://golang.org/pkg/compress/flate/
func (*API) ContentTypeOptionsMiddleware ¶ added in v0.0.4
ContentTypeOptionsMiddleware adds X-Content-Type-Options header set to nosniff to every response.
func (*API) CorsMiddleware ¶ added in v0.0.3
CorsMiddleware allows cross-origin HTTP requests to your API. The middleware is enabled by default, and can be configured via the following environment variables:
- CORS_ENABLED (bool) - CORS_ORIGINS (string) - CORS_HEADERS (string) - CORS_CREDENTIALS (bool)
func (*API) DefaultMiddlewareChain ¶ added in v0.0.3
DefaultMiddlewareChain wraps the given http.Handler in the following chain of middleware: CorsMiddleware, FrameOptionsMiddleware, ContentTypeOptionsMiddleware, CompressionMiddleware, LoggingMiddleware, RecoveryMiddleware.
func (*API) FrameOptionsMiddleware ¶ added in v0.0.4
FrameOptionsMiddleware adds X-Frame-Options header set to nosniff to every response.
func (*API) LoggingMiddleware ¶ added in v0.0.2
LoggingMiddleware wraps the given http.Handler and outputs requests in Apache-style Combined Log format. All logging is done to STDOUT only.
func (*API) MethodOverrideMiddleware ¶ added in v0.0.3
MethodOverrideMiddleware allows clients who can not perform native PUT, PATCH, or DELETE requests to specify the HTTP method in the X-HTTP-Method-Override header. The header name is case sensitive.
func (*API) RecoveryMiddleware ¶ added in v0.0.2
RecoveryMiddleware wraps the given http.Handler and recovers from panics. It wil log the stacktrace if HYPERDRIVE_ENVIRONMENT env var is not set to "production".
type Config ¶ added in v0.0.2
type Config struct { Port int `env:"PORT" envDefault:"5000"` Env string `env:"HYPERDRIVE_ENV" envDefault:"development"` GzipLevel int `env:"GZIP_LEVEL" envDefault:"-1"` CorsEnabled bool `env:"CORS_ENABLED" envDefault:"true"` CorsOrigins string `env:"CORS_ORIGINS" envDefault:"*"` CorsHeaders string `env:"CORS_HEADERS" envDefault:""` CorsCredentials bool `env:"CORS_CREDENTIALS" envDefault:"true"` }
Config holds configuration values from the environment, with sane defaults (where possible). Required configuration will throw a Fatal error if they are missing.
type ContentEncoder ¶ added in v0.0.4
type ContentEncoder interface {
Encode(interface{}) error
}
ContentEncoder interface wraps the details of encoding response bodies to support automatic Content Negotiation.
func GetEncoder ¶ added in v0.0.4
func GetEncoder(rw http.ResponseWriter, accept string) (ContentEncoder, http.ResponseWriter)
GetEncoder returns the correct ContentEncoder, determined by the Accept header, to support automatic Content Negotiation.
type DeleteHandler ¶
type DeleteHandler interface {
Delete(http.ResponseWriter, *http.Request)
}
DeleteHandler interface is satisfied if the endpoint has implemented a http.Handler method called Delete(). If this is not implemented, DELETE requests will be responded to with a `405 Method Not Allowed` error.
type Endpoint ¶
type Endpoint struct { EndpointName string EndpointDesc string EndpointPath string EndpointVersion *semver.Version }
Endpoint is a basic implementation of the Endpointer interface and can be used directly if desired.
func NewEndpoint ¶
NewEndpoint creates an instance of Endpoint.
func (*Endpoint) GetDesc ¶
GetDesc satisfies part of the Endpointer interface and returns a string containing the description of the endpoint.
func (*Endpoint) GetName ¶
GetName satisfies part of the Endpointer interface and returns a string containing the name of the endpoint.
func (*Endpoint) GetPath ¶
GetPath satisfies part of the Endpointer interface and returns a string containing the path of the endpoint, used by the Router.
This string can contain named segmets, regex, and other features as described here: http://www.gorillatoolkit.org/pkg/mux
func (*Endpoint) GetVersion ¶ added in v0.0.4
GetVersion returns a string representing the version.
type EndpointResource ¶ added in v0.0.4
type EndpointResource struct { XMLName xml.Name `json:"-" xml:"endpoint"` Resource string `json:"resource" xml:"-"` Name string `json:"name" xml:"name,attr"` Path string `json:"path" xml:"path,attr"` MethodsList string `json:"-" xml:"methods,attr"` Methods []string `json:"methods" xml:"-"` MediaTypesList string `json:"-" xml:"media-types,attr"` MediaTypes []string `json:"media-types" xml:"-"` Desc string `json:"description" xml:"description"` Params []EndpointResourceParam `json:"params" xml:"params>param"` }
EndpointResource contains information about and Endpoint, and is the hypermedia respresentation returned by the Discovery URL endpoint for API clients to learn about the Endpoint.
func NewEndpointResource ¶ added in v0.0.4
func NewEndpointResource(e Endpointer) EndpointResource
NewEndpointResource creates an instance of EndpointResource from the given Endpointer.
type EndpointResourceParam ¶ added in v0.0.5
type EndpointResourceParam struct { XMLName xml.Name `json:"-" xml:"param"` Name string `json:"name" xml:"name,attr"` Desc string `json:"description" xml:"description"` AllowedList string `json:"-" xml:"allowed,attr"` Allowed []string `json:"allowed" xml:"-"` RequiredList string `json:"-" xml:"required,attr"` Required []string `json:"required" xml:"-"` }
EndpointResourceParam contains information about endpoint parameters, and is part of the hypermedia representation returned by the Discovery URL endpoint for API clients to learn about input allowed (and/or required) by the Endpoint.
func NewEndpointResourceParam ¶ added in v0.0.5
func NewEndpointResourceParam(p parsedParam) EndpointResourceParam
NewEndpointResourceParam creates an instance of EndpointResourceParam from the given parsedParam.
type Endpointer ¶
type Endpointer interface { GetName() string GetDesc() string GetPath() string GetVersion() string }
Endpointer interface provides flexibility in how endpoints are created allowing for expressiveness in how developers make use of the hyperdrive package.
type GetHandler ¶
type GetHandler interface {
Get(http.ResponseWriter, *http.Request)
}
GetHandler interface is satisfied if the endpoint has implemented a http.Handler method called Get(). If this is not implemented, GET requests will be responded to with a `405 Method Not Allowed` error.
type JSONEncoder ¶ added in v0.0.4
JSONEncoder is an implementation of ContentEncoder and wraps the Encoder found in encoding/json package.
func (JSONEncoder) Encode ¶ added in v0.0.4
func (enc JSONEncoder) Encode(v interface{}) error
Encode encodes input as json text or returns an error.
type NullEncoder ¶ added in v0.0.4
type NullEncoder struct{}
NullEncoder is an implementation of ContentEncoder, and is the default encoder used when Content Negotiation has falied. It produces a 406 NOT ACCEPTABLE error when it's Encode() function is run.
func (NullEncoder) Encode ¶ added in v0.0.4
func (enc NullEncoder) Encode(v interface{}) error
Encode returns a 406 NOT ACCEPTABLE error.
type OptionsHandler ¶
type OptionsHandler interface {
Options(http.ResponseWriter, *http.Request)
}
OptionsHandler interface is satisfied if the endpoint has implemented a http.Handler method called Options(). If this is not implemented, OPTIONS requests will be responded to with a `200 OK` and the `Allow` header will be set with a list of all the methods your endpoint does support.
type Parameter ¶ added in v0.0.5
Parameter is an interface to allow users to create self-describing custom types to be used as endpoint params. The name and description are reusable across multiple endpoints.
type PatchHandler ¶
type PatchHandler interface {
Patch(http.ResponseWriter, *http.Request)
}
PatchHandler interface is satisfied if the endpoint has implemented a http.Handler method called Patch(). If this is not implemented, PATCH requests will be responded to with a `405 Method Not Allowed` error.
type PostHandler ¶
type PostHandler interface {
Post(http.ResponseWriter, *http.Request)
}
PostHandler interface is satisfied if the endpoint has implemented a http.Handler method called Post(). If this is not implemented, POST requests will be responded to with a `405 Method Not Allowed` error.
type PutHandler ¶
type PutHandler interface {
Put(http.ResponseWriter, *http.Request)
}
PutHandler interface is satisfied if the endpoint has implemented a http.Handler method called Put(). If this is not implemented, PUT requests will be responded to with a `405 Method Not Allowed` error.
type RootResource ¶ added in v0.0.3
type RootResource struct { XMLName xml.Name `json:"-" xml:"api"` Resource string `json:"resource" xml:"-"` Name string `json:"name" xml:"name,attr"` Endpoints []EndpointResource `json:"endpoints" xml:"endpoints>endpoint"` }
RootResource contains information about the API and its Endpoints, and is the hypermedia respresentation returned by the Discovery URL endpoint for API clients to learn about the API.
func NewRootResource ¶ added in v0.0.3
func NewRootResource(api API) *RootResource
NewRootResource creates an instance of RootResource from the given API.
func (*RootResource) AddEndpoint ¶ added in v0.0.4
func (root *RootResource) AddEndpoint(e Endpointer)
AddEndpoint adds EndpointResources to the slice of Endpoints on an instance of RootResource.
func (*RootResource) ServeHTTP ¶ added in v0.0.3
func (root *RootResource) ServeHTTP(rw http.ResponseWriter, r *http.Request)
ServeHTTP satisfies the http.Handler interface and returns the hypermedia representation of the Discovery URL.
type XMLEncoder ¶ added in v0.0.4
XMLEncoder is an implementation of ContentEncoder and wraps the Encoder found in encoding/xml package.
func (XMLEncoder) Encode ¶ added in v0.0.4
func (enc XMLEncoder) Encode(v interface{}) error
Encode encodes input as xml text or returns an error.