hyperdrive

package module
v0.0.5 Latest Latest
Warning

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

Go to latest
Published: Mar 27, 2017 License: MIT Imports: 17 Imported by: 0

README

hyperdrive Build Status GoDoc Go Report Card Coverage Status Slack Group MIT License

An opinionated micro-framework for creating Hypermedia APIs in Go.


Install

go get github.com/hyperdriven/hyperdrive

OR

glide get github.com/hyperdriven/hyperdrive

Import

import "github.com/hyperdriven/hyperdrive"

Usage

Refer to our Quick Start Guide for how to use this package.

Config

Configuration of core features are done via Environment Variables, in accordence with 12 factor principles, and is detailed here

Contributing

Refer to our Contributor's Guide to learn more about how you can partipicate.

More Info

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func BodyParams added in v0.0.5

func BodyParams(r *http.Request) url.Values

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

func GetErrorText(status int, err error) string

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

func GetParams(e Endpointer, r *http.Request) (url.Values, error)

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

func Params(r *http.Request) url.Values

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

func PathParams(r *http.Request) url.Values

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

func QueryParams(r *http.Request) url.Values

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

func NewAPI(name string, desc string) API

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

func (api *API) CompressionMiddleware(h http.Handler) http.Handler

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

func (api *API) ContentTypeOptionsMiddleware(h http.Handler) http.Handler

ContentTypeOptionsMiddleware adds X-Content-Type-Options header set to nosniff to every response.

func (*API) CorsMiddleware added in v0.0.3

func (api *API) CorsMiddleware(h http.Handler) http.Handler

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

func (api *API) DefaultMiddlewareChain(h http.Handler) http.Handler

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

func (api *API) FrameOptionsMiddleware(h http.Handler) http.Handler

FrameOptionsMiddleware adds X-Frame-Options header set to nosniff to every response.

func (*API) LoggingMiddleware added in v0.0.2

func (api *API) LoggingMiddleware(h http.Handler) http.Handler

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

func (api *API) MethodOverrideMiddleware(h http.Handler) http.Handler

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

func (api *API) RecoveryMiddleware(h http.Handler) http.Handler

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".

func (*API) Start added in v0.0.2

func (api *API) Start()

Start starts the configured http server, listening on the configured Port (default: 5000). Set the PORT environment variable to change this.

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.

func NewConfig added in v0.0.2

func NewConfig() (Config, error)

NewConfig returns an instance of config, with values loaded from ENV vars.

func (*Config) GetPort added in v0.0.2

func (c *Config) GetPort() string

GetPort returns the formatted value of config.Port, for use by the hyperdrive server, e.g. ":5000".

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

func NewEndpoint(name string, desc string, path string, version string) *Endpoint

NewEndpoint creates an instance of Endpoint.

func (*Endpoint) GetDesc

func (e *Endpoint) GetDesc() string

GetDesc satisfies part of the Endpointer interface and returns a string containing the description of the endpoint.

func (*Endpoint) GetName

func (e *Endpoint) GetName() string

GetName satisfies part of the Endpointer interface and returns a string containing the name of the endpoint.

func (*Endpoint) GetPath

func (e *Endpoint) GetPath() string

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

func (e *Endpoint) GetVersion() string

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

type JSONEncoder struct {
	Encoder *json.Encoder
}

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

type Parameter interface {
	GetName() string
	GetDesc() string
}

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

type XMLEncoder struct {
	Encoder *xml.Encoder
}

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.

Jump to

Keyboard shortcuts

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