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 and scalable request routing using a Trie based implementation, helpers to deal with JSON requests and responses, and middlewares for functionalities like CORS, Auth, Gzip, Status, ...
Example:
package main import ( "github.com/ant0ine/go-json-rest/rest" "log" "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() { api := rest.NewApi() api.Use(rest.DefaultDevStack...) router, err := rest.MakeRouter( rest.Get("/users/:id", GetUser), ) if err != nil { log.Fatal(err) } api.SetApp(router) log.Fatal(http.ListenAndServe(":8080", api.MakeHandler())) }
Index ¶
- Constants
- Variables
- func Error(w ResponseWriter, error string, code int)
- func NotFound(w ResponseWriter, r *Request)
- type AccessLogApacheMiddleware
- type AccessLogFormat
- type AccessLogJsonMiddleware
- type AccessLogJsonRecord
- type Api
- type App
- type AppSimple
- type AuthBasicMiddleware
- type ContentTypeCheckerMiddleware
- type CorsInfo
- type CorsMiddleware
- type GzipMiddleware
- type HandlerFunc
- type IfMiddleware
- type JsonIndentMiddleware
- type JsonpMiddleware
- type Middleware
- type MiddlewareSimple
- type PoweredByMiddleware
- type RecorderMiddleware
- type RecoverMiddleware
- type Request
- type ResourceHandler
- type ResponseWriter
- type Route
- type Status
- type StatusMiddleware
- type TimerMiddleware
Constants ¶
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 ¶
var DefaultCommonStack = []Middleware{ &TimerMiddleware{}, &RecorderMiddleware{}, &PoweredByMiddleware{}, &RecoverMiddleware{}, }
Defines a stack of middlewares that should be common to most of the middleware stacks.
var DefaultDevStack = []Middleware{ &AccessLogApacheMiddleware{}, &TimerMiddleware{}, &RecorderMiddleware{}, &PoweredByMiddleware{}, &RecoverMiddleware{ EnableResponseStackTrace: true, }, &JsonIndentMiddleware{}, &ContentTypeCheckerMiddleware{}, }
Defines a stack of middlewares convenient for development. Among other things: console friendly logging, JSON indentation, error stack strace in the response.
var DefaultProdStack = []Middleware{ &AccessLogApacheMiddleware{ Format: CombinedLogFormat, }, &TimerMiddleware{}, &RecorderMiddleware{}, &PoweredByMiddleware{}, &RecoverMiddleware{}, &GzipMiddleware{}, &ContentTypeCheckerMiddleware{}, }
Defines a stack of middlewares convenient for production. Among other things: Apache CombinedLogFormat logging, gzip compression.
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 AccessLogApacheMiddleware ¶
type AccessLogApacheMiddleware struct { // Logger points to the logger object used by this middleware, it defaults to // log.New(os.Stderr, "", 0). Logger *log.Logger // Format defines the format of the access log record. See AccessLogFormat for the details. // It defaults to DefaultLogFormat. Format AccessLogFormat // contains filtered or unexported fields }
AccessLogApacheMiddleware produces the access log following a format inspired by Apache mod_log_config. It depends on TimerMiddleware and RecorderMiddleware that should be in the wrapped middlewares. It also uses request.Env["REMOTE_USER"].(string) set by the auth middlewares.
func (*AccessLogApacheMiddleware) MiddlewareFunc ¶
func (mw *AccessLogApacheMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc
MiddlewareFunc makes AccessLogApacheMiddleware implement the Middleware interface.
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 AccessLogJsonMiddleware ¶
type AccessLogJsonMiddleware struct { // Logger points to the logger object used by this middleware, it defaults to // log.New(os.Stderr, "", 0). Logger *log.Logger }
AccessLogJsonMiddleware produces the access log with records written as JSON. This middleware depends on TimerMiddleware and RecorderMiddleware that must be in the wrapped middlewares. It also uses request.Env["REMOTE_USER"].(string) set by the auth middlewares.
func (*AccessLogJsonMiddleware) MiddlewareFunc ¶
func (mw *AccessLogJsonMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc
MiddlewareFunc makes AccessLogJsonMiddleware implement the Middleware interface.
type AccessLogJsonRecord ¶
type AccessLogJsonRecord struct { Timestamp *time.Time StatusCode int ResponseTime *time.Duration HttpMethod string RequestURI string RemoteUser string UserAgent string }
AccessLogJsonRecord is the data structure used by AccessLogJsonMiddleware to create the JSON records. (Public for documentation only, no public method uses it)
type Api ¶
type Api struct {
// contains filtered or unexported fields
}
Api defines a stack of Middlewares and an App.
func NewApi ¶
func NewApi() *Api
NewApi makes a new Api object. The Middleware stack is empty, and the App is nil.
func (*Api) MakeHandler ¶
MakeHandler wraps all the Middlewares of the stack and the App together, and returns an http.Handler ready to be used. If the Middleware stack is empty the App is used directly. If the App is nil, a HandlerFunc that does nothing is used instead.
func (*Api) Use ¶
func (api *Api) Use(middlewares ...Middleware)
Use pushes one or multiple middlewares to the stack for middlewares maintained in the Api object.
type App ¶
type App interface {
AppFunc() HandlerFunc
}
App defines the interface that an object should implement to be used as an app in this framework stack. The App is the top element of the stack, the other elements being middlewares.
func MakeRouter ¶
MakeRouter returns the router app. Given a set of Routes, it dispatches the request to the HandlerFunc of the first route that matches. The order of the Routes matters.
type AppSimple ¶
type AppSimple HandlerFunc
AppSimple is an adapter type that makes it easy to write an App with a simple function. eg: rest.NewApi(rest.AppSimple(func(w rest.ResponseWriter, r *rest.Request) { ... }))
func (AppSimple) AppFunc ¶
func (as AppSimple) AppFunc() HandlerFunc
AppFunc makes AppSimple implement the App interface.
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 // Callback function that should perform the authorization of the authenticated user. Called // only after an authentication success. Must return true on success, false on failure. // Optional, default to success. Authorizator func(userId string, request *Request) bool }
AuthBasicMiddleware provides a simple AuthBasic implementation. On failure, a 401 HTTP response is returned. On success, the wrapped middleware is called, and the userId is made available as request.Env["REMOTE_USER"].(string)
func (*AuthBasicMiddleware) MiddlewareFunc ¶
func (mw *AuthBasicMiddleware) MiddlewareFunc(handler HandlerFunc) HandlerFunc
MiddlewareFunc makes AuthBasicMiddleware implement the Middleware interface.
type ContentTypeCheckerMiddleware ¶
type ContentTypeCheckerMiddleware struct{}
ContentTypeCheckerMiddleware verifies the request Content-Type header and returns a StatusUnsupportedMediaType (415) HTTP error response if it's incorrect. The expected Content-Type is 'application/json' if the content is non-null. Note: If a charset parameter exists, it MUST be UTF-8.
func (*ContentTypeCheckerMiddleware) MiddlewareFunc ¶
func (mw *ContentTypeCheckerMiddleware) MiddlewareFunc(handler HandlerFunc) HandlerFunc
MiddlewareFunc makes ContentTypeCheckerMiddleware implement the Middleware interface.
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 GzipMiddleware ¶
type GzipMiddleware struct{}
GzipMiddleware is responsible for compressing the payload with gzip and setting the proper headers when supported by the client. It must be wrapped by TimerMiddleware for the compression time to be captured. And It must be wrapped by RecorderMiddleware for the compressed BYTES_WRITTEN to be captured.
func (*GzipMiddleware) MiddlewareFunc ¶
func (mw *GzipMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc
MiddlewareFunc makes GzipMiddleware 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 IfMiddleware ¶
type IfMiddleware struct { // Runtime condition that decides of the execution of IfTrue of IfFalse. Condition func(r *Request) bool // Middleware to run when the condition is true. Note that the middleware is initialized // weather if will be used or not. (Optional, pass-through if not set) IfTrue Middleware // Middleware to run when the condition is false. Note that the middleware is initialized // weather if will be used or not. (Optional, pass-through if not set) IfFalse Middleware }
IfMiddleware evaluates at runtime a condition based on the current request, and decides to execute one of the other Middleware based on this boolean.
func (*IfMiddleware) MiddlewareFunc ¶
func (mw *IfMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc
MiddlewareFunc makes TimerMiddleware implement the Middleware interface.
type JsonIndentMiddleware ¶
type JsonIndentMiddleware struct { // prefix string, as in json.MarshalIndent Prefix string // indentation string, as in json.MarshalIndent Indent string }
JsonIndentMiddleware provides JSON encoding with indentation. It could be convenient to use it during development. It works by "subclassing" the responseWriter provided by the wrapping middleware, replacing the writer.EncodeJson and writer.WriteJson implementations, and making the parent implementations ignored.
func (*JsonIndentMiddleware) MiddlewareFunc ¶
func (mw *JsonIndentMiddleware) MiddlewareFunc(handler HandlerFunc) HandlerFunc
MiddlewareFunc makes JsonIndentMiddleware implement the Middleware interface.
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 MiddlewareSimple ¶
type MiddlewareSimple func(handler HandlerFunc) HandlerFunc
MiddlewareSimple is an adapter type that makes it easy to write a Middleware with a simple function. eg: api.Use(rest.MiddlewareSimple(func(h HandlerFunc) Handlerfunc { ... }))
func (MiddlewareSimple) MiddlewareFunc ¶
func (ms MiddlewareSimple) MiddlewareFunc(handler HandlerFunc) HandlerFunc
MiddlewareFunc makes MiddlewareSimple implement the Middleware interface.
type PoweredByMiddleware ¶
type PoweredByMiddleware struct { // If specified, used as the value for the "X-Powered-By" response header. // Defaults to "go-json-rest". XPoweredBy string }
PoweredByMiddleware adds the "X-Powered-By" header to the HTTP response.
func (*PoweredByMiddleware) MiddlewareFunc ¶
func (mw *PoweredByMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc
MiddlewareFunc makes PoweredByMiddleware implement the Middleware interface.
type RecorderMiddleware ¶
type RecorderMiddleware struct{}
RecorderMiddleware keeps a record of the HTTP status code of the response, and the number of bytes written. The result is available to the wrapping handlers as request.Env["STATUS_CODE"].(int), and as request.Env["BYTES_WRITTEN"].(int64)
func (*RecorderMiddleware) MiddlewareFunc ¶
func (mw *RecorderMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc
MiddlewareFunc makes RecorderMiddleware implement the Middleware interface.
type RecoverMiddleware ¶
type RecoverMiddleware struct { // Custom logger used for logging the panic errors, // optional, defaults to log.New(os.Stderr, "", 0) Logger *log.Logger // If true, the log records will be printed as JSON. Convenient for log parsing. EnableLogAsJson bool // If true, when a "panic" happens, the error string and the stack trace will be // printed in the 500 response body. EnableResponseStackTrace bool }
RecoverMiddleware catches the panic errors that occur in the wrapped HandleFunc, and convert them to 500 responses.
func (*RecoverMiddleware) MiddlewareFunc ¶
func (mw *RecoverMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc
MiddlewareFunc makes RecoverMiddleware implement the Middleware interface.
type Request ¶
type Request struct { *http.Request // Map of parameters that have been matched in the URL Path. PathParams map[string]string // Environment used by middlewares to communicate. Env map[string]interface{} }
Request inherits from http.Request, and provides additional methods.
func (*Request) BaseUrl ¶
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 ¶
DecodeJsonPayload reads the request body and decodes the JSON using json.Unmarshal.
func (*Request) GetCorsInfo ¶
GetCorsInfo derives CorsInfo from Request.
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 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. ResourceHandler is now DEPRECATED in favor of the new Api object. See the migration guide.
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, the responseWriter object instantiated by the framework also implements many other interfaces accessible by type assertion: http.ResponseWriter, http.Flusher, http.CloseNotifier, http.Hijacker.
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 as consumed by the router. It can be instantiated directly, or using one of the shortcut methods: rest.Get, rest.Post, rest.Put, and rest.Delete.
func Delete ¶
func Delete(pathExp string, handlerFunc HandlerFunc) *Route
Delete is a shortcut method that instantiates a DELETE route. Equivalent to &Route{"DELETE", pathExp, handlerFunc}
func Get ¶
func Get(pathExp string, handlerFunc HandlerFunc) *Route
Get is a shortcut method that instantiates a GET route. See the Route object the parameters definitions. Equivalent to &Route{"GET", pathExp, handlerFunc}
func Post ¶
func Post(pathExp string, handlerFunc HandlerFunc) *Route
Post is a shortcut method that instantiates a POST route. See the Route object the parameters definitions. Equivalent to &Route{"POST", pathExp, handlerFunc}
func Put ¶
func Put(pathExp string, handlerFunc HandlerFunc) *Route
Put is a shortcut method that instantiates a PUT route. See the Route object the parameters definitions. Equivalent to &Route{"PUT", pathExp, handlerFunc}
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 }
type StatusMiddleware ¶
type StatusMiddleware struct {
// contains filtered or unexported fields
}
StatusMiddleware keeps track of various stats about the processed requests. It depends on request.Env["STATUS_CODE"] and request.Env["ELAPSED_TIME"], recorderMiddleware and timerMiddleware must be in the wrapped middlewares.
func (*StatusMiddleware) GetStatus ¶
func (mw *StatusMiddleware) GetStatus() *Status
GetStatus computes and returns a Status object based on the request informations accumulated since the start of the process.
func (*StatusMiddleware) MiddlewareFunc ¶
func (mw *StatusMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc
MiddlewareFunc makes StatusMiddleware implement the Middleware interface.
type TimerMiddleware ¶
type TimerMiddleware struct{}
TimerMiddleware computes the elapsed time spent during the execution of the wrapped handler. The result is available to the wrapping handlers as request.Env["ELAPSED_TIME"].(*time.Duration), and as request.Env["START_TIME"].(*time.Time)
func (*TimerMiddleware) MiddlewareFunc ¶
func (mw *TimerMiddleware) MiddlewareFunc(h HandlerFunc) HandlerFunc
MiddlewareFunc makes TimerMiddleware implement the Middleware interface.
Source Files ¶
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. |