restful

package module
v0.0.0-...-92e4bff Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2013 License: MIT Imports: 15 Imported by: 0

README

go-restful

package for building REST-style Web Services using Google Go

REST asks developers to use HTTP methods explicitly and in a way that's consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping:

  • GET = Retrieve
  • POST = Create if you are sending a command to the server to create a subordinate of the specified resource, using some server-side algorithm.
  • POST = Update if you are requesting the server to update one or more subordinates of the specified resource.
  • PUT = Create iff you are sending the full content of the specified resource (URL).
  • PUT = Update iff you are updating the full content of the specified resource.
  • DELETE = Delete if you are requesting the server to delete the resource
  • PATCH = Update partial content of a resource
Resources

Build Status

(c) 2012+, http://ernestmicklei.com. MIT License

Documentation

Overview

Package go-restful, a lean package for creating REST-style WebServices without magic.

Example WebService:

package landscapeservice

import (
    "github.com/emicklei/go-restful"
)

func New() *restful.WebService {
	ws := new(restful.WebService)
   	ws.Path("/applications").
		Consumes(restful.MIME_XML, restful.MIME_JSON).
		Produces(restful.MIME_XML, restful.MIME_JSON)

	ws.Route(ws.GET("/{id}").To(getApplication).
		// for documentation
		Doc("Get the Application node by its id").
		Operation("getApplication").
		Param(ws.PathParameter("id" , "the identifier for an application node")).
		Param(ws.QueryParameter("environment" , "the scope in which the application node lives")).
		Writes(Application{})) // to the response

	ws.Route(ws.POST("/").To(saveApplication).
		// for documentation
		Doc("Create or update the Application node").
		Operation("saveApplication").
		Reads(Application{})) // from the request
	return ws
}
func getApplication(request *restful.Request, response *restful.Response) {
		id := request.PathParameter("id")
		env := request.QueryParameter("environment")
		...
}
func saveApplication(request *restful.Request, response *restful.Response) {
	   response.AddHeader("X-Something","other")
	   ...
	   response.WriteEntity(anApp) // uses Accept header to detect XML/JSON

}

Example main:

func main() {
	restful.Add(landscapeservice.New())
	log.Fatal(http.ListenAndServe(":8080", nil))
}

WebServices

A WebService has a collection of Route objects that dispatch incoming Http Requests to a function calls.

type RouteFunction func(*restful.Request, *restful.Response)

A Route is defined by a HTTP method, an URL path and (optionally) the MIME types it consumes (Content-Type) and produces (Accept). This package has the logic to find the best matching Route and if found, call its Function. The (*Request, *Response) arguments provide functions for reading information from the request and writing information back to the response.

Filters

A filter dynamically intercepts requests and responses to transform or use the information contained in the requests or responses. You can use filters to perform generic logging, measurement, authentication, redirect, set response headers etc. In the restful package there are three hooks into the request,response flow where filters can be added. Each filter must define a FilterFunction:

func (req *restful.Request, resp *restful.Response, chain *restful.FilterChain)

Use the following statement to pass the request,response pair to the next filter or RouteFunction

chain.ProcessFilter(req, resp)

Global Filters

These are processed before any registered WebService.

// install a global filter (processed before any webservice)
restful.Filter(globalLogging)

WebService Filters

These are processed before any Route of a WebService.

// install a webservice filter (processed before any route)
ws.Filter(webserviceLogging).Filter(measureTime)

Route Filters

These are processed before calling the function associated with the Route.

// install 2 chained route filters (processed before calling findUser)
ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter).To(findUser))

See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-filters.go with full implementations.

Serving files

Use the Go standard http.ServeFile function to serve file system assets.

ws.Route(ws.GET("/static/{resource}").To(staticFromPathParam))
...
// http://localhost:8080/static/test.xml
// http://localhost:8080/static/
func staticFromPathParam(req *restful.Request, resp *restful.Response) {
	http.ServeFile(
		resp.ResponseWriter,
		req.Request,
		path.Join(rootdir, req.PathParameter("resource")))
}

See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-serve-static.go with full implementations.

Response Encoding

Two encodings are supported: gzip and deflate. To enable this for all responses:

restful.EnableContentEncoding = true

If a Http request includes the Accept-Encoding header then the response content will be compressed using the specified encoding.

Alternatively, you can create a Filter that performs the encoding and install it per WebService or Route. See the example https://github.com/emicklei/go-restful/blob/master/examples/restful-encoding-filter.go

Error Handling

Unexpected things happen. If a request cannot be processed because of a failure, your service needs to tell the response what happened and why. For this reason HTTP status codes exist and it is important to use the correct code in every exceptional situation.

400: Bad Request

If path or query parameters are not valid (content or type) then use http.StatusBadRequest.

id, err := strconv.Atoi(req.PathParameter("id"))
if err != nil {
	resp.WriteHeader(http.StatusBadRequest)
	return
}

404: Not Found

Despite a valid URI, the resource requested may not be available

resp.WriteHeader(http.StatusNotFound)

500: Internal Server Error

If the application logic could not process the request (or write the response) then use http.StatusInternalServerError.

question, err := application.SharedLogic.GetQuestionById(id)
if err != nil {
	log.Printf("GetQuestionById failed:", err)
	resp.WriteHeader(http.StatusInternalServerError)
	return
}

ServiceError

In addition to setting the correct (error) Http status code, you can choose to write a ServiceError message on the response:

resp.WriteEntity(restful.NewError(http.StatusBadRequest, "Non-integer {id} path parameter"))

resp.WriteEntity(restful.NewError(http.StatusInternalServerError, err.Error()))

Resources

(c) 2013, http://ernestmicklei.com. MIT License

Index

Constants

View Source
const (
	MIME_XML  = "application/xml"
	MIME_JSON = "application/json"

	HEADER_Accept          = "Accept"
	HEADER_ContentType     = "Content-Type"
	HEADER_LastModified    = "Last-Modified"
	HEADER_AcceptEncoding  = "Accept-Encoding"
	HEADER_ContentEncoding = "Content-Encoding"

	ENCODING_GZIP    = "gzip"
	ENCODING_DEFLATE = "deflate"
)
View Source
const (
	PATH_PARAMETER = iota
	QUERY_PARAMETER
	BODY_PARAMETER
	HEADER_PARAMETER
)

Variables

View Source
var DefaultResponseMimeType string

If Accept header matching fails, fall back to this type, otherwise a "406: Not Acceptable" response is returned. Valid values are restful.MIME_JSON and restful.MIME_XML Example:

restful.DefaultResponseMimeType = restful.MIME_JSON

The Dispatch function is responsible to delegating to the appropriate WebService that has been registered via Add. The default implementation is DefaultDispatch which also does some basic panic handling and closes the request body.

Example of overriding it to add basic request logging:

	restful.Dispatch = func(w http.ResponseWriter, r *http.Request) {
		fmt.Println(r.Method, r.URL)
		restful.DefaultDispatch(w, r)
	}

 Deprecated: Use filters instead.
View Source
var DoNotRecover = false

If set the true then panics will not be caught to return HTTP 500. In that case, Route functions are responsible for handling any error situation. Default value is false = recover from panics. This has performance implications.

View Source
var EnableContentEncoding = false

If EnableContentEncoding is true then the Accept-Encoding HTTP Header is inspected and a CompressingResponseWriter is used to write the response.

View Source
var Router = RouterJSR311{}

The Router is responsible for selecting the best matching Route given the input (request,response) See jsr311.go

Functions

func Add

func Add(service *WebService)

Add registers a new WebService add it to the http listeners.

func DefaultDispatch

func DefaultDispatch(httpWriter http.ResponseWriter, httpRequest *http.Request)

Dispatch the incoming Http Request to a matching WebService. Matching algorithm is conform http://jsr311.java.net/nonav/releases/1.1/spec/spec.html, see jsr311.go

func Filter

func Filter(filter FilterFunction)

Filter appends a global FilterFunction. These are called before dispatch a http.Request to a WebService.

func WantsCompressedResponse

func WantsCompressedResponse(httpRequest *http.Request) (bool, string)

WantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested.

Types

type CompressingResponseWriter

type CompressingResponseWriter struct {
	// contains filtered or unexported fields
}

CompressingResponseWriter is a http.ResponseWriter that can perform content encoding (gzip and zlib)

func NewCompressingResponseWriter

func NewCompressingResponseWriter(httpWriter http.ResponseWriter, encoding string) (*CompressingResponseWriter, error)

NewCompressingResponseWriter create a CompressingResponseWriter for a known encoding = {gzip,deflate}

func (*CompressingResponseWriter) Close

func (c *CompressingResponseWriter) Close()

Close the underlying compressor

func (*CompressingResponseWriter) Header

Header is part of http.ResponseWriter interface

func (*CompressingResponseWriter) Write

func (c *CompressingResponseWriter) Write(bytes []byte) (int, error)

Write is part of http.ResponseWriter interface It is passed through the compressor

func (*CompressingResponseWriter) WriteHeader

func (c *CompressingResponseWriter) WriteHeader(status int)

WriteHeader is part of http.ResponseWriter interface

type CurlyRouter

type CurlyRouter struct{}

CurlyRouter expects Routes with paths that contain zero or more parameters in curly brackets.

func (CurlyRouter) SelectRoute

func (c CurlyRouter) SelectRoute(
	path string,
	webServices []*WebService,
	httpWriter http.ResponseWriter,
	httpRequest *http.Request) (selectedService *WebService, selected Route, ok bool)

SelectRoute finds a Route given the input HTTP Request and report if found (ok). The HTTP writer is be used to directly communicate non-200 HTTP stati.

type FilterChain

type FilterChain struct {
	Filters []FilterFunction // ordered list of FilterFunction
	Index   int              // index into filters that is currently in progress
	Target  RouteFunction    // function to call after passing all filters
}

FilterChain is a request scoped object to process one or more filters before calling the target RouteFunction.

func (*FilterChain) ProcessFilter

func (f *FilterChain) ProcessFilter(request *Request, response *Response)

ProcessFilter passes the request,response pair through the next of Filters. Each filter can decide to proceed to the next Filter or handle the Response itself.

type FilterFunction

type FilterFunction func(*Request, *Response, *FilterChain)

FilterFunction definitions must call ProcessFilter on the FilterChain to pass on the control and eventually call the RouteFunction

type Parameter

type Parameter struct {
	// contains filtered or unexported fields
}

Parameter is for documententing the parameter used in a Http Request ParameterData kinds are Path,Query and Body

func (*Parameter) AllowMultiple

func (p *Parameter) AllowMultiple(multiple bool) *Parameter

AllowMultiple sets the allowMultiple field and return the receiver

func (*Parameter) AllowableValues

func (p *Parameter) AllowableValues(values map[string]string) *Parameter

AllowableValues sets the allowableValues field and return the receiver

func (*Parameter) Data

func (p *Parameter) Data() ParameterData

func (*Parameter) DataType

func (p *Parameter) DataType(typeName string) *Parameter

DataType sets the dataType field and return the receiver

func (*Parameter) Kind

func (p *Parameter) Kind() int

func (*Parameter) Required

func (p *Parameter) Required(required bool) *Parameter

Required sets the required field and return the receiver

type ParameterData

type ParameterData struct {
	Name, Description, DataType string
	Kind                        int
	Required                    bool
	AllowableValues             map[string]string
	AllowMultiple               bool
}

type Request

type Request struct {
	Request *http.Request
	// contains filtered or unexported fields
}

Request is a wrapper for a http Request that provides convenience methods

func (*Request) HeaderParameter

func (r *Request) HeaderParameter(name string) string

HeaderParameter returns the HTTP Header value of a Header name or empty if missing

func (*Request) PathParameter

func (r *Request) PathParameter(name string) string

PathParameter accesses the Path parameter value by its name

func (*Request) QueryParameter

func (r *Request) QueryParameter(name string) string

QueryParameter returns the (first) Query parameter value by its name

func (*Request) ReadEntity

func (r *Request) ReadEntity(entityPointer interface{}) error

ReadEntity checks the Accept header and reads the content into the entityPointer

type Response

type Response struct {
	http.ResponseWriter
	// contains filtered or unexported fields
}

Response is a wrapper on the actual http ResponseWriter It provides several convenience methods to prepare and write response content.

func (Response) AddHeader

func (r Response) AddHeader(header string, value string) Response

AddHeader is a shortcut for .Header().Add(header,value)

func (Response) InternalServerError

func (r Response) InternalServerError() Response

InternalServerError is a shortcut for .WriteHeader(http.StatusInternalServerError) DEPRECATED, use the long version

func (Response) WriteAsJson

func (r Response) WriteAsJson(value interface{}) Response

WriteAsJson is a convenience method for writing a value in json

func (Response) WriteAsXml

func (r Response) WriteAsXml(value interface{}) Response

WriteAsXml is a convenience method for writing a value in xml (requires Xml tags on the value)

func (Response) WriteEntity

func (r Response) WriteEntity(value interface{}) Response

WriteEntity marshals the value using the representation denoted by the Accept Header (XML or JSON) If no Accept header is specified (or */*) then return the Content-Type as specified by the first in the Route.Produces. If an Accept header is specified then return the Content-Type as specified by the first in the Route.Produces that is matched with the Accept header. Current implementation ignores any q-parameters in the Accept Header.

func (Response) WriteError

func (r Response) WriteError(httpStatus int, err error) Response

WriteError is a convenience method for an error HTTP status with the actual error

func (Response) WriteServiceError

func (r Response) WriteServiceError(httpStatus int, err ServiceError) Response

WriteServiceError is a convenience method for a responding with a ServiceError and a status

type Route

type Route struct {
	Method   string
	Produces []string
	Consumes []string
	Path     string
	Function RouteFunction
	Filters  []FilterFunction

	// documentation
	Doc                     string
	Operation               string
	ParameterDocs           []*Parameter
	ReadSample, WriteSample interface{} // structs that model an example request or response payload
	// contains filtered or unexported fields
}

Route binds a HTTP Method,Path,Consumes combination to a RouteFunction.

type RouteBuilder

type RouteBuilder struct {
	// contains filtered or unexported fields
}

RouteBuilder is a helper to construct Routes.

func (*RouteBuilder) Build

func (b *RouteBuilder) Build() Route

Build creates a new Route using the specification details collected by the RouteBuilder

func (*RouteBuilder) Consumes

func (b *RouteBuilder) Consumes(mimeTypes ...string) *RouteBuilder

Specify what MIME types can be consumes ; the Accept Http header must matched any of these

func (*RouteBuilder) Doc

func (b *RouteBuilder) Doc(documentation string) *RouteBuilder

Doc tells what this route is all about. Optional.

func (*RouteBuilder) Filter

func (b *RouteBuilder) Filter(filter FilterFunction) *RouteBuilder

Filter appends a FilterFunction to the end of filters for this Route to build.

func (*RouteBuilder) Method

func (b *RouteBuilder) Method(method string) *RouteBuilder

Method specifies what HTTP method to match. Required.

func (*RouteBuilder) Operation

func (b *RouteBuilder) Operation(name string) *RouteBuilder

Operation allows you to document what the acutal method/function call is of the Route.

func (*RouteBuilder) Param

func (b *RouteBuilder) Param(parameter *Parameter) *RouteBuilder

Param allows you to document the parameters of the Route.

func (*RouteBuilder) Path

func (b *RouteBuilder) Path(subPath string) *RouteBuilder

Path specifies the relative (w.r.t WebService root path) URL path to match. Default is "/".

func (*RouteBuilder) Produces

func (b *RouteBuilder) Produces(mimeTypes ...string) *RouteBuilder

Produces specifies what MIME types can be produced ; the matched one will appear in the Content-Type Http header.

func (*RouteBuilder) Reads

func (b *RouteBuilder) Reads(sample interface{}) *RouteBuilder

Reads tells what resource type will be read from the request payload. Optional.

func (*RouteBuilder) To

func (b *RouteBuilder) To(function RouteFunction) *RouteBuilder

To bind the route to a function. If this route is matched with the incoming Http Request then call this function with the *Request,*Response pair. Required.

func (*RouteBuilder) Writes

func (b *RouteBuilder) Writes(sample interface{}) *RouteBuilder

Writes tells what resource type will be written as the response payload. Optional.

type RouteFunction

type RouteFunction func(*Request, *Response)

Signature of a function that can be bound to a Route.

type RouteSelector

type RouteSelector interface {

	// SelectRoute finds a Route given the input HTTP Request and report if found (ok).
	// The HTTP writer is be used to directly communicate non-200 HTTP stati.
	SelectRoute(
		path string,
		webServices []*WebService,
		httpWriter http.ResponseWriter,
		httpRequest *http.Request) (selectedService *WebService, selected Route, ok bool)
}

A RouteSelector finds the best matching Route given the input HTTP Request

type RouterJSR311

type RouterJSR311 struct{}

func (RouterJSR311) SelectRoute

func (r RouterJSR311) SelectRoute(
	path string,
	webServices []*WebService,
	httpWriter http.ResponseWriter,
	httpRequest *http.Request) (selectedService *WebService, selectedRoute Route, ok bool)

type ServiceError

type ServiceError struct {
	Code    int
	Message string
}

ServiceError is a transport object to pass information about a non-Http error occurred in a WebService while processing a request.

func NewError

func NewError(code int, message string) ServiceError

Return a new ServiceError using the code and reason

func (ServiceError) Error

func (self ServiceError) Error() string

Return a text representation of the service error

type WebService

type WebService struct {
	// contains filtered or unexported fields
}

WebService holds a collection of Route values that bind a Http Method + URL Path to a function.

func RegisteredWebServices

func RegisteredWebServices() []*WebService

RegisteredWebServices returns the collections of added Dispatchers (WebService is an implementation)

func (*WebService) BodyParameter

func (w *WebService) BodyParameter(name, description string) *Parameter

BodyParameter creates a new Parameter of kind Body for documentation purposes. It is initialized as required without a DataType.

func (*WebService) Consumes

func (w *WebService) Consumes(accepts ...string) *WebService

Produces specifies that this WebService can consume one or more MIME types.

func (*WebService) DELETE

func (w *WebService) DELETE(subPath string) *RouteBuilder

DELETE is a shortcut for .Method("DELETE").Path(subPath)

func (*WebService) Filter

func (w *WebService) Filter(filter FilterFunction) *WebService

Filter adds a filter function to the chain of filters applicable to all its Routes

func (*WebService) GET

func (w *WebService) GET(subPath string) *RouteBuilder

GET is a shortcut for .Method("GET").Path(subPath)

func (*WebService) HeaderParameter

func (w *WebService) HeaderParameter(name, description string) *Parameter

HeaderParameter creates a new Parameter of kind (Http) Header for documentation purposes. It is initialized as not required with string as its DataType.

func (*WebService) Method

func (w *WebService) Method(httpMethod string) *RouteBuilder

Method creates a new RouteBuilder and initialize its http method

func (*WebService) PATCH

func (w *WebService) PATCH(subPath string) *RouteBuilder

PATCH is a shortcut for .Method("PATCH").Path(subPath)

func (*WebService) POST

func (w *WebService) POST(subPath string) *RouteBuilder

POST is a shortcut for .Method("POST").Path(subPath)

func (*WebService) PUT

func (w *WebService) PUT(subPath string) *RouteBuilder

PUT is a shortcut for .Method("PUT").Path(subPath)

func (*WebService) Param

func (w *WebService) Param(parameter *Parameter) *WebService

Param adds a PathParameter to document parameters used in the root path.

func (*WebService) Path

func (w *WebService) Path(root string) *WebService

Path specifies the root URL template path of the WebService. All Routes will be relative to this path.

func (*WebService) PathParameter

func (w *WebService) PathParameter(name, description string) *Parameter

PathParameter creates a new Parameter of kind Path for documentation purposes. It is initialized as required with string as its DataType.

func (WebService) PathParameters

func (w WebService) PathParameters() []*Parameter

PathParameters return the path parameter names for (shared amoung its Routes)

func (*WebService) Produces

func (w *WebService) Produces(contentTypes ...string) *WebService

Produces specifies that this WebService can produce one or more MIME types.

func (*WebService) QueryParameter

func (w *WebService) QueryParameter(name, description string) *Parameter

QueryParameter creates a new Parameter of kind Query for documentation purposes. It is initialized as not required with string as its DataType.

func (WebService) RootPath

func (w WebService) RootPath() string

RootPath returns the RootPath associated with this WebService. Default "/"

func (*WebService) Route

func (w *WebService) Route(builder *RouteBuilder) *WebService

Route creates a new Route using the RouteBuilder and add to the ordered list of Routes.

func (WebService) Routes

func (w WebService) Routes() []Route

Routes returns the Routes associated with this WebService

Directories

Path Synopsis
Package swagger implements the structures of the Swagger (https://github.com/wordnik/swagger-core/wiki) specification
Package swagger implements the structures of the Swagger (https://github.com/wordnik/swagger-core/wiki) specification

Jump to

Keyboard shortcuts

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