rest

package
v2.1.0+incompatible Latest Latest
Warning

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

Go to latest
Published: Nov 30, 2014 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

A quick and easy way to setup a RESTful JSON API

http://ant0ine.github.io/go-json-rest/

Go-Json-Rest is a thin layer on top of net/http that helps building RESTful JSON APIs easily. It provides fast URL routing using a Trie based implementation, helpers to deal with JSON requests and responses, and middlewares for additional functionalities like CORS, Auth, Gzip ...

Example:

package main

import (
        "github.com/ant0ine/go-json-rest/rest"
        "net/http"
)

type User struct {
        Id   string
        Name string
}

func GetUser(w rest.ResponseWriter, req *rest.Request) {
        user := User{
                Id:   req.PathParam("id"),
                Name: "Antoine",
        }
        w.WriteJson(&user)
}

func main() {
        handler := rest.ResourceHandler{}
        handler.SetRoutes(
                rest.Route{"GET", "/users/:id", GetUser},
        )
        http.ListenAndServe(":8080", &handler)
}

Note about the URL routing: Instead of using the usual "evaluate all the routes and return the first regexp that matches" strategy, it uses a Trie data structure to perform the routing. This is more efficient, and scales better for a large number of routes. It supports the :param and *splat placeholders in the route strings.

Index

Constants

View Source
const (
	// Common Log Format (CLF).
	CommonLogFormat = "%h %l %u %t \"%r\" %s %b"

	// NCSA extended/combined log format.
	CombinedLogFormat = "%h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\""

	// Default format, colored output and response time, convenient for development.
	DefaultLogFormat = "%t %S\033[0m \033[36;1m%Dμs\033[0m \"%r\" \033[1;30m%u \"%{User-Agent}i\"\033[0m"
)

Variables

This section is empty.

Functions

func Error

func Error(w ResponseWriter, error string, code int)

Error produces an error response in JSON with the following structure, '{"Error":"My error message"}' The standard plain text net/http Error helper can still be called like this: http.Error(w, "error message", code)

func NotFound

func NotFound(w ResponseWriter, r *Request)

NotFound produces a 404 response with the following JSON, '{"Error":"Resource not found"}' The standard plain text net/http NotFound helper can still be called like this: http.NotFound(w, r.Request)

Types

type AccessLogFormat

type AccessLogFormat string

AccessLogFormat defines the format of the access log record. This implementation is a subset of Apache mod_log_config. (See http://httpd.apache.org/docs/2.0/mod/mod_log_config.html)

%b content length in bytes, - if 0
%B content length in bytes
%D response elapsed time in microseconds
%h remote address
%H server protocol
%l identd logname, not supported, -
%m http method
%P process id
%q query string
%r first line of the request
%s status code
%S status code preceeded by a terminal color
%t time of the request
%T response elapsed time in seconds, 3 decimals
%u remote user, - if missing
%{User-Agent}i user agent, - if missing
%{Referer}i referer, - is missing

Some predefined formats are provided as contants.

type AccessLogJsonRecord

type AccessLogJsonRecord struct {
	Timestamp    *time.Time
	StatusCode   int
	ResponseTime *time.Duration
	HttpMethod   string
	RequestURI   string
	RemoteUser   string
	UserAgent    string
}

When EnableLogAsJson is true, this object is dumped as JSON in the Logger. (Public for documentation only, no public method uses it).

type AuthBasicMiddleware

type AuthBasicMiddleware struct {

	// Realm name to display to the user. (Required)
	Realm string

	// Callback function that should perform the authentication of the user based on userId and password.
	// Must return true on success, false on failure. (Required)
	Authenticator func(userId string, password string) bool
}

AuthBasicMiddleware provides a simple AuthBasic implementation. It can be used before routing to protect all the endpoints, see PreRoutingMiddlewares. Or it can be used to wrap a particular endpoint HandlerFunc.

func (*AuthBasicMiddleware) MiddlewareFunc

func (mw *AuthBasicMiddleware) MiddlewareFunc(handler HandlerFunc) HandlerFunc

MiddlewareFunc tries to authenticate the user. It sends a 401 on failure, and executes the wrapped handler on success. Note that, on success, the userId is made available in the environment at request.Env["REMOTE_USER"]

type CorsInfo

type CorsInfo struct {
	IsCors      bool
	IsPreflight bool
	Origin      string
	OriginUrl   *url.URL

	// The header value is converted to uppercase to avoid common mistakes.
	AccessControlRequestMethod string

	// The header values are normalized with http.CanonicalHeaderKey.
	AccessControlRequestHeaders []string
}

CorsInfo contains the CORS request info derived from a rest.Request.

type CorsMiddleware

type CorsMiddleware struct {

	// Reject non CORS requests if true. See CorsInfo.IsCors.
	RejectNonCorsRequests bool

	// Function excecuted for every CORS requests to validate the Origin. (Required)
	// Must return true if valid, false if invalid.
	// For instance: simple equality, regexp, DB lookup, ...
	OriginValidator func(origin string, request *Request) bool

	// List of allowed HTTP methods. Note that the comparison will be made in uppercase
	// to avoid common mistakes. And that the Access-Control-Allow-Methods response header
	// also uses uppercase.
	// (see CorsInfo.AccessControlRequestMethod)
	AllowedMethods []string

	// List of allowed HTTP Headers. Note that the comparison will be made with
	// noarmalized names (http.CanonicalHeaderKey). And that the response header
	// also uses normalized names.
	// (see CorsInfo.AccessControlRequestHeaders)
	AllowedHeaders []string

	// List of headers used to set the Access-Control-Expose-Headers header.
	AccessControlExposeHeaders []string

	// User to se the Access-Control-Allow-Credentials response header.
	AccessControlAllowCredentials bool

	// Used to set the Access-Control-Max-Age response header, in seconds.
	AccessControlMaxAge int
	// contains filtered or unexported fields
}

CorsMiddleware provides a configurable CORS implementation.

func (*CorsMiddleware) MiddlewareFunc

func (mw *CorsMiddleware) MiddlewareFunc(handler HandlerFunc) HandlerFunc

MiddlewareFunc makes CorsMiddleware implement the Middleware interface.

type HandlerFunc

type HandlerFunc func(ResponseWriter, *Request)

HandlerFunc defines the handler function. It is the go-json-rest equivalent of http.HandlerFunc.

func WrapMiddlewares

func WrapMiddlewares(middlewares []Middleware, handler HandlerFunc) HandlerFunc

WrapMiddlewares calls the MiddlewareFunc methods in the reverse order and returns an HandlerFunc ready to be executed. This can be used to wrap a set of middlewares, post routing, on a per Route basis.

type JsonpMiddleware

type JsonpMiddleware struct {

	// Name of the query string parameter used to specify the
	// the name of the JS callback used for the padding.
	// Defaults to "callback".
	CallbackNameKey string
}

JsonpMiddleware provides JSONP responses on demand, based on the presence of a query string argument specifying the callback name.

func (*JsonpMiddleware) MiddlewareFunc

func (mw *JsonpMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc

MiddlewareFunc returns a HandlerFunc that implements the middleware.

type Middleware

type Middleware interface {
	MiddlewareFunc(handler HandlerFunc) HandlerFunc
}

Middleware defines the interface that objects must implement in order to wrap a HandlerFunc and be used in the middleware stack.

type Request

type Request struct {
	*http.Request

	// Map of parameters that have been matched in the URL Path.
	PathParams map[string]string

	// Environement used by middlewares to communicate.
	Env map[string]interface{}
}

Request inherits from http.Request, and provides additional methods.

func (*Request) BaseUrl

func (r *Request) BaseUrl() *url.URL

BaseUrl returns a new URL object with the Host and Scheme taken from the request. (without the trailing slash in the host)

func (*Request) DecodeJsonPayload

func (r *Request) DecodeJsonPayload(v interface{}) error

DecodeJsonPayload reads the request body and decodes the JSON using json.Unmarshal.

func (*Request) GetCorsInfo

func (r *Request) GetCorsInfo() *CorsInfo

GetCorsInfo derives CorsInfo from Request.

func (*Request) PathParam

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

PathParam provides a convenient access to the PathParams map.

func (*Request) UrlFor

func (r *Request) UrlFor(path string, queryParams map[string][]string) *url.URL

UrlFor returns the URL object from UriBase with the Path set to path, and the query string built with queryParams.

type ResourceHandler

type ResourceHandler struct {

	// If true, and if the client accepts the Gzip encoding, the response payloads
	// will be compressed using gzip, and the corresponding response header will set.
	EnableGzip bool

	// If true, the JSON payload will be written in one line with no space.
	DisableJsonIndent bool

	// If true, the status service will be enabled. Various stats and status will
	// then be available at GET /.status in a JSON format.
	EnableStatusService bool

	// If true, when a "panic" happens, the error string and the stack trace will be
	// printed in the 500 response body.
	EnableResponseStackTrace bool

	// If true, the records logged to the access log and the error log will be
	// printed as JSON. Convenient for log parsing.
	// See the AccessLogJsonRecord type for details of the access log JSON record.
	EnableLogAsJson bool

	// If true, the handler does NOT check the request Content-Type. Otherwise, it
	// must be set to 'application/json' if the content is non-null.
	// Note: If a charset parameter exists, it MUST be UTF-8
	EnableRelaxedContentType bool

	// Optional global middlewares that can be used to wrap the all REST endpoints.
	// They are used in the defined order, the first wrapping the second, ...
	// They are run first, wrapping all go-json-rest middlewares,
	// * request.PathParams is not set yet
	// * "panic" won't be caught and converted to 500
	// * request.Env["STATUS_CODE"] and request.Env["ELAPSED_TIME"] are set.
	// They can be used for extra logging, or reporting.
	// (see statsd example in in https://github.com/ant0ine/go-json-rest-examples)
	OuterMiddlewares []Middleware

	// Optional global middlewares that can be used to wrap the all REST endpoints.
	// They are used in the defined order, the first wrapping the second, ...
	// They are run pre REST routing, request.PathParams is not set yet.
	// They are run post auto error handling, "panic" will be converted to 500 errors.
	// They can be used for instance to manage CORS or authentication.
	// (see the CORS and Auth examples in https://github.com/ant0ine/go-json-rest-examples)
	PreRoutingMiddlewares []Middleware

	// Custom logger for the access log,
	// optional, defaults to log.New(os.Stderr, "", 0)
	Logger *log.Logger

	// Define the format of the access log record.
	// When EnableLogAsJson is false, this format is used to generate the access log.
	// See AccessLogFormat for the options and the predefined formats.
	// Defaults to a developement friendly format specified by the Default constant.
	LoggerFormat AccessLogFormat

	// If true, the access log will be fully disabled.
	// (the log middleware is not even instantiated, avoiding any performance penalty)
	DisableLogger bool

	// Custom logger used for logging the panic errors,
	// optional, defaults to log.New(os.Stderr, "", 0)
	ErrorLogger *log.Logger

	// Custom X-Powered-By value, defaults to "go-json-rest".
	XPoweredBy string

	// If true, the X-Powered-By header will NOT be set.
	DisableXPoweredBy bool
	// contains filtered or unexported fields
}

ResourceHandler implements the http.Handler interface and acts a router for the defined Routes. The defaults are intended to be developemnt friendly, for production you may want to turn on gzip and disable the JSON indentation for instance.

func (*ResourceHandler) GetStatus

func (rh *ResourceHandler) GetStatus() *Status

GetStatus returns a Status object. EnableStatusService must be true.

func (*ResourceHandler) ServeHTTP

func (rh *ResourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

This makes ResourceHandler implement the http.Handler interface. You probably don't want to use it directly.

func (*ResourceHandler) SetRoutes

func (rh *ResourceHandler) SetRoutes(routes ...*Route) error

SetRoutes defines the Routes. The order the Routes matters, if a request matches multiple Routes, the first one will be used.

type ResponseWriter

type ResponseWriter interface {

	// Identical to the http.ResponseWriter interface
	Header() http.Header

	// Use EncodeJson to generate the payload, write the headers with http.StatusOK if they
	// are not already written, then write the payload.
	// The Content-Type header is set to "application/json", unless already specified.
	WriteJson(v interface{}) error

	// Encode the data structure to JSON, mainly used to wrap ResponseWriter in middlewares.
	EncodeJson(v interface{}) ([]byte, error)

	// Similar to the http.ResponseWriter interface, with additional JSON related headers set.
	WriteHeader(int)
}

A ResponseWriter interface dedicated to JSON HTTP response. Note that the object instantiated by the ResourceHandler that implements this interface, also happens to implement http.ResponseWriter, http.Flusher and http.CloseNotifier.

type Route

type Route struct {

	// Any HTTP method. It will be used as uppercase to avoid common mistakes.
	HttpMethod string

	// A string like "/resource/:id.json".
	// Placeholders supported are:
	// :paramName that matches any char to the first '/' or '.'
	// #paramName that matches any char to the first '/'
	// *paramName that matches everything to the end of the string
	// (placeholder names must be unique per PathExp)
	PathExp string

	// Code that will be executed when this route is taken.
	Func HandlerFunc
}

Route defines a route. It's used with SetRoutes.

func RouteObjectMethod

func RouteObjectMethod(httpMethod string, pathExp string, objectInstance interface{}, objectMethod string) *Route

RouteObjectMethod creates a Route that points to an object method. It can be convenient to point to an object method instead of a function, this helper makes it easy by passing the object instance and the method name as parameters.

DEPRECATED: Since Go 1.1 and the introduction of the Method Values, this is now useless, and will probably be removed from the next major version of go-json-rest (v3) See: https://golang.org/doc/go1.1#method_values

func (*Route) MakePath

func (route *Route) MakePath(pathParams map[string]string) string

MakePath generates the path corresponding to this Route and the provided path parameters. This is used for reverse route resolution.

type Status

type Status struct {
	Pid                    int
	UpTime                 string
	UpTimeSec              float64
	Time                   string
	TimeUnix               int64
	StatusCodeCount        map[string]int
	TotalCount             int
	TotalResponseTime      string
	TotalResponseTimeSec   float64
	AverageResponseTime    string
	AverageResponseTimeSec float64
}

Status contains stats and status information. It is returned by GetStatus. These information can be made available as an API endpoint, see the "status" example to install the following status route. GET /.status returns something like:

{
  "Pid": 21732,
  "UpTime": "1m15.926272s",
  "UpTimeSec": 75.926272,
  "Time": "2013-03-04 08:00:27.152986 +0000 UTC",
  "TimeUnix": 1362384027,
  "StatusCodeCount": {
    "200": 53,
    "404": 11
  },
  "TotalCount": 64,
  "TotalResponseTime": "16.777ms",
  "TotalResponseTimeSec": 0.016777,
  "AverageResponseTime": "262.14us",
  "AverageResponseTimeSec": 0.00026214
}

Directories

Path Synopsis
Utility functions to help writing tests for a Go-Json-Rest app Go comes with net/http/httptest to help writing test for an http server.
Utility functions to help writing tests for a Go-Json-Rest app Go comes with net/http/httptest to help writing test for an http server.
Special Trie implementation for HTTP routing.
Special Trie implementation for HTTP routing.

Jump to

Keyboard shortcuts

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