rest

package
v2.9.3+incompatible Latest Latest
Warning

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

Go to latest
Published: Dec 2, 2016 License: BSD-3-Clause Imports: 21 Imported by: 6

Documentation

Overview

The Tideland Go REST Server Library provides the package rest 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
)
View Source
const (
	// Standard REST status codes.
	StatusOK                  = http.StatusOK
	StatusCreated             = http.StatusCreated
	StatusNoContent           = http.StatusNoContent
	StatusBadRequest          = http.StatusBadRequest
	StatusUnauthorized        = http.StatusUnauthorized
	StatusNotFound            = http.StatusNotFound
	StatusConflict            = http.StatusConflict
	StatusInternalServerError = http.StatusInternalServerError

	// Standard REST content types.
	ContentTypePlain      = "text/plain"
	ContentTypeHTML       = "text/html"
	ContentTypeXML        = "application/xml"
	ContentTypeJSON       = "application/json"
	ContentTypeGOB        = "application/vnd.tideland.gob"
	ContentTypeURLEncoded = "application/x-www-form-urlencoded"
)

Variables

This section is empty.

Functions

func NegativeFeedback

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

NegativeFeedback writes a negative feedback envelope to the formatter.

func PositiveFeedback

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

PositiveFeedback writes a positive feedback envelope to the formatter.

Types

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
}

func EnvironmentFromContext

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

EnvironmentFromContext retrieves the environment out of a context.

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(status 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
}

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 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.
	Domain() string

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

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

	// 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() Query
}

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 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 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 Query

type Query 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
}

Query allows typed access with default values to a jobs request values passed as query.

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.

Jump to

Keyboard shortcuts

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