rest

package
v0.0.0-...-e0dbbc2 Latest Latest
Warning

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

Go to latest
Published: Jan 9, 2017 License: Apache-2.0 Imports: 19 Imported by: 3

Documentation

Overview

Package rest provides the ability to construct JSON REST endpoints and clients.

Endpoints are provided by constructing an Endpoint struct and registering Route objects. Route objects are constructed from handlers and Path objects. Each HTTP request received by the Endpoint will be routed to the handler of the route with a matching path.

Paths can contain variable components denoted by a leading ':' character. These variable arguments will be used to automatically populate the arguments of the handler. Constant components take precedence over variable components during routing. Note that a request can only be routed to a single handler and duplicate paths are therefore rejected.

Clients are provided by the Client struct which allows the incremental construction of REST request. The response is sent when calling the Client.Send() function and the return can be processed via the Response.GetBody() function which will check for various HTTP error conditions.

gorest currently only supports JSON requests with the exception of error messages which are communicated as strings. Request and response body must therefore be compatible with the encoding/json package.

Index

Constants

View Source
const (
	// EndpointError indicates that the remote endpoint returned an error.
	EndpointError = "endpoint-error"

	// HandlerError indicates that the route handler returned an error.
	HandlerError = "handler-error"

	// UnknownRoute indicates that no matching routes were found for the path.
	UnknownRoute = "unknown-route"

	// UnexpectedStatusCode indicates that the returned status code of an HTTP
	// request was not expected.
	UnexpectedStatusCode = "unexpected-status-code"

	// UnsupportedContentType indicates that the content-type header of an HTTP
	// request contained an unsupported value.
	UnsupportedContentType = "unsupported-content-type"

	// ReadBodyError indicates that an error occured while reading the body of
	// an HTTP request or response.
	ReadBodyError = "ready-body-error"

	// NewRequestError indicates that an error occured while creating an HTTP
	// request.
	NewRequestError = "new-request-error"

	// SendRequestError indicates that an error occured while sending an HTTP
	// request.
	SendRequestError = "send-request-error"

	// TimeoutError indicates that the request timed out while sending an HTTP
	// request.
	TimeoutError = "timeout-error"

	// UnmarshalError indicates that an error occured while deserializing the
	// body of an HTTP response.
	UnmarshalError = "unmarshal-error"

	// GzipError indicates that an error occured while compressing the
	// body of an HTTP response into gzip.
	GzipError = "gzip-error"

	// MarshalError indicates that an error occured while serializing the body
	// of an HTTP request.
	MarshalError = "marshal-error"
)

Variables

View Source
var DefaultMux = new(Mux)

DefaultMux is the default Mux used by Serve which uses the http.DefaultServeMux as the DefaultHandler in Mux if no routes match.

Functions

func AddRoute

func AddRoute(path, method string, handler interface{})

AddRoute adds a REST route to DefaultMux. See Route type for further details on REST route specification.

func AddService

func AddService(routable Routable)

AddService adds a Routable service to DefaultMux.

func JoinPath

func JoinPath(a, b string) string

JoinPath joins two partial paths into a single path.

func ListenAndServe

func ListenAndServe(addr string, mux *Mux) error

ListenAndServe is a proxy for the http.ListenAndServe function but using the DefaultMux.

func ListenAndServeTLS

func ListenAndServeTLS(addr string, certFile string, keyFile string, mux *Mux) error

ListenAndServeTLS is a proxy for the http.ListenAndServeTLS function but using the DefaultMux.

func Serve

func Serve(l net.Listener, mux *Mux) error

Serve is a proxy for the http.Serve function but using the DefaultMux.

func SplitPath

func SplitPath(path string) (split []string)

SplitPath breaks a REST path into its components.

Types

type Client

type Client struct {
	*http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Header is a list of HTTP requests that will be added to every requests
	// originating from this client.
	Header http.Header

	// GzipLevel is used to compress requests to a certain level, using gzip.
	GzipLevel int

	// Limit sets a hard limit on the number of concurrent requests. If not set
	// then no limits are imposed.
	Limit uint
	// contains filtered or unexported fields
}

Client is a convenience REST client which simplifies the creation of REST requests.

func (*Client) NewRequest

func (client *Client) NewRequest(method string) *Request

NewRequest creates a new Request object for the given HTTP method.

type CodedError

type CodedError struct {
	Code int
	Sub  error
}

CodedError is used to control the HTTP return code of a REST request when an error occurs.

\todo Need to replace this by a solution that allows the modification of ANY part of the HTTP response.

func (*CodedError) Error

func (err *CodedError) Error() string

Error returns the string representation of the error.

type Error

type Error struct {
	// Type is the type of the error.
	Type ErrorType

	// Sub is the wrapped error.
	Sub error
}

Error is a typed wrapper for an error that occured while processing a REST request.

func ErrorFmt

func ErrorFmt(errT ErrorType, format string, args ...interface{}) *Error

ErrorFmt creates a new Error object with the given type.

We can't call this function Errorf because of go vet who chokes if the first argument isn't the format string.

func (*Error) Error

func (err *Error) Error() string

Error returns the string representation of the error.

type ErrorType

type ErrorType string

ErrorType is used to categories errors reported into types.

type Mux

type Mux struct {

	// Root is the path prefix of all the routes to be matched by this
	// mux. Must be set before calling Init and can't be changed
	// afterwards.
	Root string

	// ErrorFunc is called for all errors that passes through this mux. The
	// returned value will overwrite the current error and will be returned to
	// the client instead.. If it's return value is a rest.CodedError then the
	// status code of the error object will be used.
	ErrorFunc func(ErrorType, error) error

	DefaultHandler http.Handler
	// contains filtered or unexported fields
}

Mux routes incoming bid requests to the registered routes. Implements the http.Handler interface.

The mux currently only supports JSON content-type for regular message and text/plain for error messages.

func (*Mux) AddRoute

func (mux *Mux) AddRoute(routes ...*Route)

AddRoute adds all the given routes to the mux.

func (*Mux) AddService

func (mux *Mux) AddService(routables ...Routable)

AddService adds all the routes returned by the Routable objects to the mux.

func (*Mux) Init

func (mux *Mux) Init()

Init initializes the object.

func (*Mux) ServeHTTP

func (mux *Mux) ServeHTTP(writer http.ResponseWriter, httpReq *http.Request)

ServeHTTP services incoming HTTP request by routing them to one of the registered routes. Handles all marshalling of input and outputs as well as any required path parsing.

type Path

type Path []PathItem

Path is an array of PathItem which represents the templated path of an HTTP query.

The format of a path is a series of item seperated by '/' characters. An item can either be a constant or an argument which starts with leading ':' character. A full path examples looks like the following:

/a/:b/c

Where a and c are both constants and b is an argument.

func NewPath

func NewPath(rawPath string) (path Path)

NewPath breaks up the given path into PathItem to form a new Path object. It panics if it's unable to parse the path.

func (Path) NumArgs

func (path Path) NumArgs() (n int)

NumArgs returns the number of items in the path where IsArg is true.

func (Path) String

func (path Path) String() string

String returns the string representation of the path.

type PathItem

type PathItem struct {
	Name  string
	IsArg bool
}

PathItem represents a single item in a path which can either be an argument or a constant. The name of an argument is used purely for documentation purposes while the name of a constant is its value.

func (PathItem) String

func (item PathItem) String() string

String returns the string representation of the item.

type Request

type Request struct {

	// REST is the client that originated the request. Can be nil.
	REST *Client

	// Client is the http.Client used to send the request. Defaults to
	// http.DefaultClient and can changed via the SetClient method.
	Client *http.Client

	// Host is the address of the remote REST endpoint where requests should be
	// sent to.
	Host string

	// Root is a prefix that will be preprended to all path requests created by
	// this client.
	Root string

	// Path is the absolute path where the Request should be routed to on the
	// remote endpoint. Can be changed via the SetPath method.
	Path string

	// Query contains the url parameters and values that will be sent with the
	// request. Paramerters can be added via the AddParam method.
	Query url.Values

	// Method is the HTTP verb used for the HTTP request.
	Method string

	// Header contains all the headers to be added to the HTTP request. Can be
	// changed via the AddHeader method.
	Header http.Header

	// GzipLevel is used to compress requests using gzip.
	GzipLevel int

	// Body is the JSON serialized body of the HTTP request. Can be set via the
	// SetBody method.
	Body []byte

	HTTP *http.Request
	// contains filtered or unexported fields
}

Request is used to gradually construct REST requests and send them to a remote endpoint. Request object should be created via the NewRequest function or the Client.NewRequest function and filled in via the SetXxx and AddXxx functions. Finally the request is sent via the Send function which returns a Response object.

func NewRequest

func NewRequest(host, method string) *Request

NewRequest creates a new Request object to be sent to the given host using the given HTTP verb.

func (*Request) AddHeader

func (req *Request) AddHeader(key, value string) *Request

AddHeader adds the given header to the request.

func (*Request) AddParam

func (req *Request) AddParam(key, value string) *Request

AddParam adds a parameter to the query string.

func (*Request) Send

func (req *Request) Send() *Response

Send attempts to send the request to the remote endpoint and returns a Response which contains the result.

func (*Request) SetBody

func (req *Request) SetBody(obj interface{}) *Request

SetBody marshals the given objects and sets it as the body of the request. The Content-Length header will be automatically set.

func (*Request) SetClient

func (req *Request) SetClient(client *http.Client) *Request

SetClient selects the http.Client to be used to execute the requests.

func (*Request) SetGzipLevel

func (req *Request) SetGzipLevel(level int) *Request

SetGzipLevel sets the compression level, must be called before SetBody.

func (*Request) SetHost

func (req *Request) SetHost(host string) *Request

SetHost selects the host where the request will be sent.

func (*Request) SetPath

func (req *Request) SetPath(path string, args ...interface{}) *Request

SetPath formats and sets the path where the request will be routed to. Note that the root is prefixed to the path before formatting the string.

func (*Request) SetRawBody

func (req *Request) SetRawBody(obj json.RawMessage) *Request

type Response

type Response struct {

	// Request is the request that originated the response.
	Request *Request

	// Code is the http status code returned by the endpoint.
	Code int

	// Header holds the headers of the HTTP response.
	Header http.Header

	// Body holds the raw unmarshalled body of the HTTP response. GetBody can be
	// used to unmarshal the body.
	Body []byte

	// Error is set if an error occured while sending the request.
	Error *Error

	// Latency indicates how long the request round-trip took.
	Latency time.Duration
}

Response holds the result of a sent REST request. The response should be read via the GetBody method which checks the various fields to detect errors.

func (*Response) GetBody

func (resp *Response) GetBody(obj interface{}) (err *Error)

GetBody checks the various fields of the response for errors and unmarshals the response body if the given object is not nil. If an error is detected, the error type and error will be returned instead.

type Routable

type Routable interface {

	// RESTRoutes returns a list of Route that can be used for routing REST
	// requests.
	RESTRoutes() Routes
}

Routable is used to detect objects that are routable by an Endpoint.

type Route

type Route struct {

	// Path is the templated path required by this route. See Handler for the
	// rules related to path.
	Path Path

	// Method represents the HTTP verb required by this route.
	Method string

	// Handler is a function to be invoked whenever for a given HTTP method and
	// templated path.
	//
	// The function can only return at most 2 values where one will be an error
	// object and the other will be the body of the HTTP response.
	//
	// The function needs enough arguments to accept the Path arguments and,
	// optionally, the body of the request. The path arguments will be applied
	// in the same order as the function arguments with the last function
	// argument being the body.
	//
	// If any of the previous rules are broken, Route will panic when Init is
	// called.
	Handler interface{}

	// GzipLevel is used to set the response gzip compression level.
	GzipLevel int
	// contains filtered or unexported fields
}

Route associates a handler which should be invoked for a given HTTP method and templated path.

func NewRoute

func NewRoute(path, method string, handler interface{}) *Route

NewRoute creates and initializes a new Route from the method, path and handler.

func NewRouteGzip

func NewRouteGzip(path, method string, handler interface{}, level int) *Route

NewRouteGzip creates and initializea a new Route from the method, path and handler. And will gzip compress the returned value.

func (*Route) HasBodyParam

func (route *Route) HasBodyParam() bool

func (*Route) Init

func (route *Route) Init()

Init initializes the object.

func (*Route) JsonSchema

func (route *Route) JsonSchema() string

JsonSchema returns a json schema for the body if there is a body.

func (*Route) String

func (route *Route) String() string

String returns a string represenation of the object suitable for debugging.

type Routes

type Routes []*Route

Routes is convenience type that represents a list of Route objects.

func (Routes) Len

func (routes Routes) Len() int

func (Routes) Less

func (routes Routes) Less(i, j int) bool

func (Routes) Swap

func (routes Routes) Swap(i, j int)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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