rest

package
v2.15.5+incompatible Latest Latest
Warning

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

Go to latest
Published: Nov 10, 2017 License: BSD-3-Clause Imports: 21 Imported by: 6

Documentation

Overview

Package rest of Tideland GoREST provides types for the implementation of servers with a RESTful API. The business has to be implemented in types fullfilling the ResourceHandler interface. This basic interface only allows the initialization of the handler. More interesting are the other interfaces like GetResourceHandler which defines the Get() method for the HTTP request method GET. Others are for PUT, POST, HEAD, PATCH, DELETE, and OPTIONS. Their according methods get a Job as argument. It provides convenient helpers for the processing of the job.

type myHandler struct {
    id string
}

func NewMyHandler(id string) rest.ResourceHandler {
    return &myHandler{id}
}

func (h *myHandler) ID() string {
    return h.id
}

func (h *myHandler) Init(env rest.Environment, domain, resource string) error {
    // Nothing to do in this example.
    return nil
}

// Get handles reading of resources, here simplified w/o
// error handling.
func (h *myHandler) Get(job rest.Job) (bool, error) {
    id := job.ResourceID()
    if id == "" {
       all := model.GetAllData()
       job.JSON(true).Write(all)
       return true, nil
    }
    one := model.GetOneData(id)
    job.JSON(true).Write(one)
    return true, nil
}

The processing methods return two values: a boolean and an error. The latter is pretty clear, it signals a job processing error. The boolean is more interesting. Registering a handler is based on a domain and a resource. The URL

/<DOMAIN>/<RESOURCE>

leads to a handler, or even better, to a list of handlers. All are used as long as the returned boolean value is true. E.g. the first handler can check the authentication, the second one the authorization, and the third one does the business. Additionally the URL

/<DOMAIN>/<RESOURCE>/<ID>

provides the resource identifier via Job.ResourceID().

The handlers then are deployed to the Multiplexer which implements the Handler interface of the net/http package. So the typical order is

mux := rest.NewMultiplexer(ctx, cfg)

to start the multiplexer with a given context and the configuration for the multiplexer. The configuration is using the Tideland Go Library etc.Etc, parameters can be found at the NewMultiplexer documentation. After creating the multiplexer call

mux.Register("domain", "resource-type-a", NewTypeAHandler("foo"))
mux.Register("domain", "resource-type-b", NewTypeBHandler("bar"))
mux.Register("admin", "user", NewUserManagementHandler())

to register the handlers per domain and resource. The server then can be started by the standard

http.ListenAndServe(":8000", mux)

Additionally further handlers can be registered or running ones removed during the runtime.

Index

Constants

View Source
const (
	ErrDuplicateHandler = iota + 1
	ErrInitHandler
	ErrIllegalRequest
	ErrNoHandler
	ErrNoGetHandler
	ErrNoHeadHandler
	ErrNoPutHandler
	ErrNoPostHandler
	ErrNoPatchHandler
	ErrNoDeleteHandler
	ErrNoOptionsHandler
	ErrMethodNotSupported
	ErrUploadingFile
	ErrInvalidContentType
	ErrNoCachedTemplate
	ErrQueryValueNotFound
	ErrNoServerDefined
	ErrCannotPrepareRequest
	ErrHTTPRequestFailed
	ErrProcessingRequestContent
	ErrContentNotKeyValue
	ErrReadingResponse
)

Error codes of the rest package.

View Source
const (
	StatusOK                  = http.StatusOK
	StatusCreated             = http.StatusCreated
	StatusNoContent           = http.StatusNoContent
	StatusBadRequest          = http.StatusBadRequest
	StatusUnauthorized        = http.StatusUnauthorized
	StatusForbidden           = http.StatusForbidden
	StatusNotFound            = http.StatusNotFound
	StatusMethodNotAllowed    = http.StatusMethodNotAllowed
	StatusNotAcceptable       = http.StatusNotAcceptable
	StatusGone                = http.StatusGone
	StatusPreconditionFailed  = http.StatusPreconditionFailed
	StatusUnprocessableEntity = http.StatusUnprocessableEntity
	StatusLocked              = http.StatusLocked
	StatusTooManyRequests     = http.StatusTooManyRequests
	StatusConflict            = http.StatusConflict
	StatusInternalServerError = http.StatusInternalServerError
)

Standard REST status codes.

View Source
const (
	ContentTypePlain      = "text/plain"
	ContentTypeHTML       = "text/html"
	ContentTypeXML        = "application/xml"
	ContentTypeJSON       = "application/json"
	ContentTypeGOB        = "application/vnd.tideland.gob"
	ContentTypeURLEncoded = "application/x-www-form-urlencoded"
)

Standard REST content types.

View Source
const (
	PathDomain     = 0
	PathResource   = 1
	PathResourceID = 2
)

Path indexes for the different parts.

Variables

This section is empty.

Functions

func NegativeFeedback

func NegativeFeedback(f Formatter, statusCode int, msg string, args ...interface{}) (bool, error)

NegativeFeedback writes a negative feedback envelope to the formatter. The message is also logged.

func PositiveFeedback

func PositiveFeedback(f Formatter, payload interface{}, msg string, args ...interface{}) (bool, error)

PositiveFeedback writes a positive feedback envelope to the formatter.

Types

type CreateResourceHandler

type CreateResourceHandler interface {
	Create(job Job) (bool, error)
}

CreateResourceHandler is the additional interface for handlers understanding the verb POST but mapping it to method Create() according to the REST conventions.

type DeleteResourceHandler

type DeleteResourceHandler interface {
	Delete(job Job) (bool, error)
}

DeleteResourceHandler is the additional interface for handlers understanding the verb DELETE.

type Environment

type Environment interface {
	// Context returns the context of the environment.
	Context() context.Context

	// Basepath returns the configured basepath.
	Basepath() string

	// DefaultDomain returns the configured default domain.
	DefaultDomain() string

	// DefaultResource returns the configured default resource.
	DefaultResource() string

	// TemplatesCache returns the template cache.
	TemplatesCache() TemplatesCache
}

Environment describes the environment of a RESTful application.

func EnvironmentFromContext

func EnvironmentFromContext(ctx context.Context) (Environment, bool)

EnvironmentFromContext retrieves the environment out of a context.

type Feedback

type Feedback struct {
	StatusCode int         `json:"statusCode" xml:"statusCode"`
	Status     string      `json:"status" xml:"status"`
	Message    string      `json:"message,omitempty" xml:"message,omitempty"`
	Payload    interface{} `json:"payload,omitempty" xml:"payload,omitempty"`
}

Feedback is a helper to give a qualified feedback in RESTful requests. It contains wether the request has been successful, a message, and in case of success some payload if wanted.

type Formatter

type Formatter interface {
	// Write encodes the passed data to implementers format and writes
	// it with the passed status code and possible header values to the
	// response writer.
	Write(statusCode int, data interface{}, headers ...KeyValue) error

	// Read checks if the request content type matches the implementers
	// format, reads its body and decodes it to the value pointed to by
	// data.
	Read(data interface{}) error
}

Formatter allows reading or writing in handler methods based on the implementing formats like JSON, XML, or GOB.

type GetResourceHandler

type GetResourceHandler interface {
	Get(job Job) (bool, error)
}

GetResourceHandler is the additional interface for handlers understanding the verb GET.

type HeadResourceHandler

type HeadResourceHandler interface {
	Head(job Job) (bool, error)
}

HeadResourceHandler is the additional interface for handlers understanding the verb HEAD.

type InfoResourceHandler

type InfoResourceHandler interface {
	Info(job Job) (bool, error)
}

InfoResourceHandler is the additional interface for handlers understanding the verb OPTION but mapping it to method Info() according to the REST conventions.

type Job

type Job interface {
	// Return the Job as string.
	fmt.Stringer

	// Environment returns the server environment.
	Environment() Environment

	// Request returns the used Go HTTP request.
	Request() *http.Request

	// ResponseWriter returns the used Go HTTP response writer.
	ResponseWriter() http.ResponseWriter

	// Domain returns the requests domain. It's deprecated,
	// use Job.Path().Domain() instead.
	Domain() string

	// Resource returns the requests resource. It's deprecated,
	// use Job.Path().Resource() instead.
	Resource() string

	// ResourceID return the requests resource ID. It's deprecated,
	// use Job.Path().JoinedResourceID() instead.
	ResourceID() string

	// Path returns access to the request path inside the URL.
	Path() Path

	// Context returns a job context also containing the
	// job itself.
	Context() context.Context

	// EnhanceContext allows to enhance the job context
	// values, a deadline, a timeout, or a cancel. So
	// e.g. a first handler in a handler queue can
	// store authentication information in the context
	// and a following handler can use it (see the
	// JWTAuthorizationHandler).
	EnhanceContext(func(ctx context.Context) context.Context)

	// Version returns the requested API version for this job. If none
	// is set the version 1.0.0 will be returned as default. It will
	// be retrieved aut of the header Version.
	Version() version.Version

	// SetVersion allows to set an API version for the response. If
	// none is set the version 1.0.0 will be set as default. It will
	// be set in the header Version.
	SetVersion(v version.Version)

	// AcceptsContentType checks if the requestor accepts a given content type.
	AcceptsContentType(contentType string) bool

	// HasContentType checks if the sent content has the given content type.
	HasContentType(contentType string) bool

	// Languages returns the accepted language with the quality values.
	Languages() Languages

	// InternalPath builds an internal path out of the passed parts.
	InternalPath(domain, resource, resourceID string, query ...KeyValue) string

	// Redirect to a domain, resource and resource ID (optional).
	Redirect(domain, resource, resourceID string)

	// Renderer returns a template renderer.
	Renderer() Renderer

	// GOB returns a GOB formatter.
	GOB() Formatter

	// JSON returns a JSON formatter.
	JSON(html bool) Formatter

	// XML returns a XML formatter.
	XML() Formatter

	// Query returns a convenient access to query values.
	Query() Values

	// Form returns a convenient access to form values.
	Form() Values
}

Job encapsulates all the needed information for handling a request.

func JobFromContext

func JobFromContext(ctx context.Context) (Job, bool)

JobFromContext retrieves the job out of a context.

type KeyValue

type KeyValue struct {
	Key   string
	Value interface{}
}

KeyValue assigns a value to a key.

func (KeyValue) String

func (kv KeyValue) String() string

String prints the encoded form key=value for URLs.

type KeyValues

type KeyValues []KeyValue

KeyValues is a number of key/value pairs.

func (KeyValues) String

func (kvs KeyValues) String() string

String prints the encoded form key=value joind by & for URLs.

type Language

type Language struct {
	Locale string
	Value  float64
}

Language is the valued language a request accepts as response.

type Languages

type Languages []Language

Languages is the ordered set of accepted languages.

func (Languages) Len

func (ls Languages) Len() int

Len returns the number of languages to fulfill the sort interface.

func (Languages) Less

func (ls Languages) Less(i, j int) bool

Less returns if the language with the index i has a smaller value than the one with index j to fulfill the sort interface.

func (Languages) Swap

func (ls Languages) Swap(i, j int)

Swap swaps the languages with the indexes i and j.

type ModifyResourceHandler

type ModifyResourceHandler interface {
	Modify(job Job) (bool, error)
}

ModifyResourceHandler is the additional interface for handlers understanding the verb PATCH but mapping it to method Modify() according to the REST conventions.

type Multiplexer

type Multiplexer interface {
	http.Handler

	// Register adds a resource handler for a given domain and resource.
	Register(domain, resource string, handler ResourceHandler) error

	// RegisterAll allows to register multiple handler in one run.
	RegisterAll(registrations Registrations) error

	// RegisteredHandlers returns the ID stack of registered handlers
	// for a domain and resource.
	RegisteredHandlers(domain, resource string) []string

	// Deregister removes one, more, or all resource handler for a
	// given domain and resource.
	Deregister(domain, resource string, ids ...string)
}

Multiplexer enhances the http.Handler interface by registration an deregistration of handlers.

func NewMultiplexer

func NewMultiplexer(ctx context.Context, cfg etc.Etc) Multiplexer

NewMultiplexer creates a new HTTP multiplexer. The passed context will be used if a handler requests a context from a job, the configuration allows to configure the multiplexer. The allowed parameters are

{etc
    {basepath /}
    {default-domain default}
    {default-resource default}
    {ignore-favicon true}
}

The values shown here are the default values if the configuration is nil or missing these settings.

type OptionsResourceHandler

type OptionsResourceHandler interface {
	Options(job Job) (bool, error)
}

OptionsResourceHandler is the additional interface for handlers understanding the verb OPTION.

type PatchResourceHandler

type PatchResourceHandler interface {
	Patch(job Job) (bool, error)
}

PatchResourceHandler is the additional interface for handlers understanding the verb PATCH.

type Path

type Path interface {
	// Length returns the number of parts of the path.
	Length() int

	// ContainsSubResourceIDs returns true, if the path doesn't
	// end after the resource ID, e.g. to address items of an order.
	//
	// Example: /shop/orders/12345/item/1
	ContainsSubResourceIDs() bool

	// Part returns the parts of the URL path based on the
	// index or an empty string.
	Part(index int) string

	// Domain returns the requests domain.
	Domain() string

	// Resource returns the requests resource.
	Resource() string

	// ResourceID returns the requests resource ID.
	ResourceID() string

	// JoinedResourceID returns the requests resource ID together
	// with all following parts of the path.
	JoinedResourceID() string
}

Path provides access to the parts of a request path interesting for handling a job.

type PostResourceHandler

type PostResourceHandler interface {
	Post(job Job) (bool, error)
}

PostResourceHandler is the additional interface for handlers understanding the verb POST.

type PutResourceHandler

type PutResourceHandler interface {
	Put(job Job) (bool, error)
}

PutResourceHandler is the additional interface for handlers understanding the verb PUT.

type ReadResourceHandler

type ReadResourceHandler interface {
	Read(job Job) (bool, error)
}

ReadResourceHandler is the additional interface for handlers understanding the verb GET but mapping it to method Read() according to the REST conventions.

type Registration

type Registration struct {
	Domain   string
	Resource string
	Handler  ResourceHandler
}

Registration encapsulates one handler registration.

type Registrations

type Registrations []Registration

Registrations is a number handler registratons.

type Renderer

type Renderer interface {
	// Render executes the pre-parsed template with the data.
	// It also sets the content type header.
	Render(id string, data interface{}) error

	// LoadAndRender checks if the template with the given id
	// has already been parsed. In this case it will use it,
	// otherwise the template will be loaded, parsed, added
	// to the cache, and used then.
	LoadAndRender(id, filename, contentType string, data interface{}) error
}

Renderer renders templates. It is returned by a Job and knows where to render it.

type ResourceHandler

type ResourceHandler interface {
	// ID returns the deployment ID of the handler.
	ID() string

	// Init initializes the resource handler after registrations.
	Init(env Environment, domain, resource string) error
}

ResourceHandler is the base interface for all resource handlers understanding the REST verbs. It allows the initialization and returns an id that has to be unique for the combination of domain and resource. So it can later be removed again.

type TemplatesCache

type TemplatesCache interface {
	// Parse parses a raw template an stores it.
	Parse(id, rawTmpl, contentType string) error

	// LoadAndParse loads a template out of the filesystem,
	// parses and stores it.
	LoadAndParse(id, filename, contentType string) error

	// Render executes the pre-parsed template with the data.
	// It also sets the content type header.
	Render(rw http.ResponseWriter, id string, data interface{}) error

	// LoadAndRender checks if the template with the given id
	// has already been parsed. In this case it will use it,
	// otherwise the template will be loaded, parsed, added
	// to the cache, and used then.
	LoadAndRender(rw http.ResponseWriter, id, filename, contentType string, data interface{}) error
}

TemplatesCache caches and renders templates.

type UpdateResourceHandler

type UpdateResourceHandler interface {
	Update(job Job) (bool, error)
}

UpdateResourceHandler is the additional interface for handlers understanding the verb PUT but mapping it to method Update() according to the REST conventions.

type Values

type Values interface {
	// ValueAsString retrieves the string value of a given key. If it
	// doesn't exist the default value dv is returned.
	ValueAsString(key, dv string) string

	// ValueAsBool retrieves the bool value of a given key. If it
	// doesn't exist the default value dv is returned.
	ValueAsBool(key string, dv bool) bool

	// ValueAsInt retrieves the int value of a given key. If it
	// doesn't exist the default value dv is returned.
	ValueAsInt(key string, dv int) int

	// ValueAsFloat64 retrieves the float64 value of a given key. If it
	// doesn't exist the default value dv is returned.
	ValueAsFloat64(key string, dv float64) float64

	// ValueAsTime retrieves the string value of a given key and
	// interprets it as time with the passed format. If it
	// doesn't exist the default value dv is returned.
	ValueAsTime(key, layout string, dv time.Time) time.Time

	// ValueAsDuration retrieves the duration value of a given key.
	// If it doesn't exist the default value dv is returned.
	ValueAsDuration(key string, dv time.Duration) time.Duration
}

Values allows typed access with default values to a jobs request values passed as query or form.

Jump to

Keyboard shortcuts

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