Movatterモバイル変換


[0]ホーム

URL:


rest

package
v0.2.0Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2019 License:MITImports:16Imported by:133

Details

Repository

github.com/rs/rest-layer

Links

Documentation

Overview

Package rest is a `net/http` handler responsible for HTTP RESTful implementationfor the REST Layer framework.

This package is part of the rest-layer project. Seehttp://rest-layer.io forfull REST Layer documentation.

Example
package mainimport ("log""net/http""net/url""github.com/rs/cors""github.com/rs/rest-layer/resource""github.com/rs/rest-layer/resource/testing/mem""github.com/rs/rest-layer/rest""github.com/rs/rest-layer/schema")func main() {var (// Define a user resource schemauser = schema.Schema{Fields: schema.Fields{"id": {Required: true,// When a field is read-only, on default values or hooks can// set their value. The client can't change it.ReadOnly: true,// This is a field hook called when a new user is created.// The schema.NewID hook is a provided hook to generate a// unique id when no value is provided.OnInit: schema.NewID,// The Filterable and Sortable allows usage of filter and sort// on this field in requests.Filterable: true,Sortable:   true,Validator: &schema.String{Regexp: "^[0-9a-f]{32}$",},},"created": {Required:   true,ReadOnly:   true,Filterable: true,Sortable:   true,OnInit:     schema.Now,Validator:  &schema.Time{},},"updated": {Required:   true,ReadOnly:   true,Filterable: true,Sortable:   true,OnInit:     schema.Now,// The OnUpdate hook is called when the item is edited. Here we use// provided Now hook which just return the current time.OnUpdate:  schema.Now,Validator: &schema.Time{},},// Define a name field as required with a string validator"name": {Required:   true,Filterable: true,Validator: &schema.String{MaxLen: 150,},},},}// Define a post resource schemapost = schema.Schema{Fields: schema.Fields{// schema.*Field are shortcuts for common fields (identical to users' same fields)"id":      schema.IDField,"created": schema.CreatedField,"updated": schema.UpdatedField,// Define a user field which references the user owning the post.// See bellow, the content of this field is enforced by the fact// that posts is a sub-resource of users."user": {Required:   true,Filterable: true,Validator: &schema.Reference{Path: "users",},},"public": {Filterable: true,Validator:  &schema.Bool{},},// Sub-documents are handled via a sub-schema"meta": {Schema: &schema.Schema{Fields: schema.Fields{"title": {Required: true,Validator: &schema.String{MaxLen: 150,},},"body": {Validator: &schema.String{MaxLen: 100000,},},},},},},})// Create a REST API root resourceindex := resource.NewIndex()// Add a resource on /users[/:user_id]users := index.Bind("users", user, mem.NewHandler(), resource.Conf{// We allow all REST methods// (rest.ReadWrite is a shortcut for []rest.Mode{Create, Read, Update, Delete, List})AllowedModes: resource.ReadWrite,})// Bind a sub resource on /users/:user_id/posts[/:post_id]// and reference the user on each post using the "user" field of the posts resource.posts := users.Bind("posts", "user", post, mem.NewHandler(), resource.Conf{// Posts can only be read, created and deleted, not updatedAllowedModes: []resource.Mode{resource.Read, resource.List, resource.Create, resource.Delete},})// Add a friendly alias to public posts// (equivalent to /users/:user_id/posts?filter={"public":true})posts.Alias("public", url.Values{"filter": []string{"{\"public\"=true}"}})// Create API HTTP handler for the resource graphapi, err := rest.NewHandler(index)if err != nil {log.Fatalf("Invalid API configuration: %s", err)}// Add cors supporth := cors.New(cors.Options{OptionsPassthrough: true}).Handler(api)// Bind the API under /api/ pathhttp.Handle("/api/", http.StripPrefix("/api/", h))// Serve itlog.Print("Serving API on http://localhost:8080")if err := http.ListenAndServe(":8080", nil); err != nil {log.Fatal(err)}}

Index

Examples

Constants

This section is empty.

Variables

View Source
var (// ErrNotFound represents a 404 HTTP error.ErrNotFound = &Error{http.StatusNotFound, "Not Found",nil}// ErrForbidden represents a 403 HTTP error.ErrForbidden = &Error{http.StatusForbidden, "Forbidden",nil}// ErrPreconditionFailed happens when a conditional request condition is not met.ErrPreconditionFailed = &Error{http.StatusPreconditionFailed, "Precondition Failed",nil}// ErrConflict happens when another thread or node modified the data// concurrently with our own thread in such a way we can't securely apply// the requested changes.ErrConflict = &Error{http.StatusConflict, "Conflict",nil}// ErrInvalidMethod happens when the used HTTP method is not supported for// this resource.ErrInvalidMethod = &Error{http.StatusMethodNotAllowed, "Invalid Method",nil}// ErrClientClosedRequest is returned when the client closed the connection// before the server was able to finish processing the request.ErrClientClosedRequest = &Error{499, "Client Closed Request",nil}// ErrNotImplemented happens when a requested feature is not implemented.ErrNotImplemented = &Error{http.StatusNotImplemented, "Not Implemented",nil}// ErrGatewayTimeout is returned when the specified timeout for the request// has been reached before the server was able to process it.ErrGatewayTimeout = &Error{http.StatusGatewayTimeout, "Deadline Exceeded",nil}// ErrUnknown is thrown when the origin of the error can't be identified.ErrUnknown = &Error{520, "Unknown Error",nil})

Functions

funcIndexFromContext

func IndexFromContext(ctxcontext.Context) (resource.Index,bool)

IndexFromContext extracts the router from the given net/context.

Types

typeDefaultResponseFormatter

type DefaultResponseFormatter struct {}

DefaultResponseFormatter provides a base response formatter to be used bydefault. This formatter can easily be extended or replaced by implementingResponseFormatter interface and setting it on Handler.ResponseFormatter.

func (DefaultResponseFormatter)FormatError

func (fDefaultResponseFormatter) FormatError(ctxcontext.Context, headershttp.Header, errerror, skipBodybool) (context.Context, interface{})

FormatError implements ResponseFormatter.

func (DefaultResponseFormatter)FormatItem

func (fDefaultResponseFormatter) FormatItem(ctxcontext.Context, headershttp.Header, i *resource.Item, skipBodybool) (context.Context, interface{})

FormatItem implements ResponseFormatter.

func (DefaultResponseFormatter)FormatList

func (fDefaultResponseFormatter) FormatList(ctxcontext.Context, headershttp.Header, l *resource.ItemList, skipBodybool) (context.Context, interface{})

FormatList implements ResponseFormatter.

typeDefaultResponseSender

type DefaultResponseSender struct {}

DefaultResponseSender provides a base response sender to be used by default.This sender can easily be extended or replaced by implementing ResponseSenderinterface and setting it on Handler.ResponseSender.

func (DefaultResponseSender)Send

func (sDefaultResponseSender) Send(ctxcontext.Context, whttp.ResponseWriter, statusint, headershttp.Header, body interface{})

Send sends headers with the given status and marshal the data in JSON.

typeError

type Error struct {// Code defines the error code to be used for the error and for the HTTP// status.Codeint// Message is the error message.Messagestring// Issues holds per fields errors if any.Issues map[string][]interface{}}

Error defines a REST error with optional per fields error details.

funcNewError

func NewError(errerror) *Error

NewError returns a rest.Error from an standard error.

If the the inputted error is recognized, the appropriate rest.Error is mapped.

func (*Error)Error

func (e *Error) Error()string

Error returns the error as string

typeHandler

type Handler struct {// ResponseFormatter can be changed to extend the DefaultResponseFormatter.ResponseFormatterResponseFormatter// ResponseSender can be changed to extend the DefaultResponseSender.ResponseSenderResponseSender// FallbackHandlerFunc is called when REST layer doesn't find a route for// the request. If not set, a 404 or 405 standard REST error is returned.FallbackHandlerFunc func(ctxcontext.Context, whttp.ResponseWriter, r *http.Request)// contains filtered or unexported fields}

Handler is a net/http compatible handler used to serve the configured RESTAPI.

funcNewHandler

func NewHandler(iresource.Index) (*Handler,error)

NewHandler creates an new REST API HTTP handler with the specified resourceindex.

func (*Handler)ServeHTTP

func (h *Handler) ServeHTTP(whttp.ResponseWriter, r *http.Request)

ServeHTTP handles requests as a http.Handler.

func (*Handler)ServeHTTPC

func (h *Handler) ServeHTTPC(ctxcontext.Context, whttp.ResponseWriter, r *http.Request)

ServeHTTPC handles requests as a xhandler.HandlerC (deprecated).

typeResourcePath

type ResourcePath []*ResourcePathComponent

ResourcePath is the list of ResourcePathComponent leading to the requested resource

func (ResourcePath)ParentsExist

func (pResourcePath) ParentsExist(ctxcontext.Context)error

ParentsExist checks if the each intermediate parents in the path exist andreturn either a ErrNotFound or an error returned by on of the intermediateresource.

func (ResourcePath)Path

func (pResourcePath) Path()string

Path returns the path to the resource to be used with resource.Root.GetResource.

func (*ResourcePath)Prepend

func (p *ResourcePath) Prepend(rsrc *resource.Resource, fieldstring, value interface{})

Prepend add the given resource using the provided field and value as a "ghost" resourceprefix to the resource path.

The effect will be a 404 error if the doesn't have an item with the id matching to theprovided value.

This will also require that all subsequent resources in the path have this resource's"value" set on their "field" field.

Finally, all created resources at this path will also have this field and value set by default.

func (ResourcePath)Values

func (pResourcePath) Values() map[string]interface{}

Values returns all the key=value pairs defined by the resource path.

typeResourcePathComponent

type ResourcePathComponent struct {// Name is the endpoint name used to bind the resourceNamestring// Field is the resource's field used to filter targeted resourceFieldstring// Value holds the resource's id valueValue interface{}// Resource references the resourceResource *resource.Resource}

ResourcePathComponent represents the path of resource and sub-resources of a given request's resource

typeResponseFormatter

type ResponseFormatter interface {// FormatItem formats a single item in a format ready to be serialized by the ResponseSenderFormatItem(ctxcontext.Context, headershttp.Header, i *resource.Item, skipBodybool) (context.Context, interface{})// FormatList formats a list of items in a format ready to be serialized by the ResponseSenderFormatList(ctxcontext.Context, headershttp.Header, l *resource.ItemList, skipBodybool) (context.Context, interface{})// FormatError formats a REST formated error or a simple error in a format ready to be serialized by the ResponseSenderFormatError(ctxcontext.Context, headershttp.Header, errerror, skipBodybool) (context.Context, interface{})}

ResponseFormatter defines an interface responsible for formatting a thedifferent types of response objects.

typeResponseSender

type ResponseSender interface {// Send serialize the body, sets the given headers and write everything to// the provided response writer.Send(ctxcontext.Context, whttp.ResponseWriter, statusint, headershttp.Header, body interface{})}

ResponseSender defines an interface responsible for serializing and sendingthe response to the http.ResponseWriter.

Example
package mainimport ("context""net/http""github.com/rs/rest-layer/resource""github.com/rs/rest-layer/rest")type myResponseFormatter struct {// Extending default response senderrest.DefaultResponseFormatter}// Add a wrapper around the list with pagination infofunc (r myResponseFormatter) FormatList(ctx context.Context, headers http.Header, l *resource.ItemList, skipBody bool) (context.Context, interface{}) {ctx, data := r.DefaultResponseFormatter.FormatList(ctx, headers, l, skipBody)return ctx, map[string]interface{}{"meta": map[string]int{"total":  l.Total,"offset": l.Offset,},"list": data,}}func main() {index := resource.NewIndex()api, _ := rest.NewHandler(index)api.ResponseFormatter = myResponseFormatter{}}

typeRouteMatch

type RouteMatch struct {// Method is the HTTP method used on the resource.Methodstring// ResourcePath is the list of intermediate resources followed by the// targeted resource. Each intermediate resource much match all the previous// resource components of this path and newly created resources will have// their corresponding fields filled with resource path information// (resource.field => resource.value).ResourcePathResourcePath// Params is the list of client provided parameters (thru query-string or alias).Paramsurl.Values}

RouteMatch represent a REST request's matched resource with the method toapply and its parameters.

funcFindRoute

func FindRoute(indexresource.Index, req *http.Request) (*RouteMatch,error)

FindRoute returns the REST route for the given request.

funcRouteFromContext

func RouteFromContext(ctxcontext.Context) (*RouteMatch,bool)

RouteFromContext extracts the matched route from the given net/context.

func (*RouteMatch)Queryadded inv0.2.0

func (r *RouteMatch) Query() (*query.Query, *Error)

Query builds a query object from the matched route

func (*RouteMatch)Release

func (r *RouteMatch) Release()

Release releases the route so it can be reused.

func (*RouteMatch)Resource

func (r *RouteMatch) Resource() *resource.Resource

Resource returns the last resource path's resource.

func (*RouteMatch)ResourceID

func (r *RouteMatch) ResourceID() interface{}

ResourceID returns the last resource path's resource id value if any.

If this method returns a non nil value, it means the route is an item request,otherwise it's a collection request.

Source Files

View all Source files

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f orF : Jump to
y orY : Canonical URL
go.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.Learn more.

[8]ページ先頭

©2009-2025 Movatter.jp