Documentation
¶
Overview ¶
Package apirouter is a lightweight API router middleware for CORS, logging, and standardized error handling.
This package is intended to be used with Julien Schmidt's httprouter and uses MrZ's go-logger package.
Index ¶
- Constants
- func FilterMap(params *parameters.Params, filterOutFields []string) (filtered *parameters.Params)
- func FindString(needle string, haystack []string) int
- func GetAuthToken(req *http.Request) (token string, ok bool)
- func GetClientIPAddress(req *http.Request) string
- func GetCustomData(req *http.Request) (data interface{}, ok bool)
- func GetIPFromRequest(req *http.Request) (ip string, ok bool)
- func GetParams(req *http.Request) *parameters.Params
- func GetRequestID(req *http.Request) (id string, ok bool)
- func JSONEncode(e *json.Encoder, objects interface{}, allowed []string) error
- func JSONEncodeHierarchy(w io.Writer, objects interface{}, allowed interface{}) error
- func NoCache(w http.ResponseWriter, req *http.Request)
- func PermitParams(params *parameters.Params, allowedKeys []string)
- func ReturnJSONEncode(w http.ResponseWriter, code int, e *json.Encoder, objects interface{}, ...) (err error)
- func ReturnResponse(w http.ResponseWriter, req *http.Request, code int, data interface{})
- func SetAuthToken(req *http.Request, authToken string) *http.Request
- func SetCustomData(req *http.Request, data interface{}) *http.Request
- func SetOnRequest(req *http.Request, keyName paramRequestKey, value interface{}) *http.Request
- func SnakeCase(str string) string
- func StandardHandlerToHandle(next http.Handler) httprouter.Handle
- type APIError
- type APIResponseWriter
- type AllowedKeys
- type InternalStack
- type Middleware
- type Router
- func (r *Router) BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string, ...) httprouter.Handle
- func (r *Router) Request(h httprouter.Handle) httprouter.Handle
- func (r *Router) RequestNoLogging(h httprouter.Handle) httprouter.Handle
- func (r *Router) SetCrossOriginHeaders(w http.ResponseWriter, req *http.Request, _ httprouter.Params)
- type Stack
Examples ¶
Constants ¶
const ( // ErrCodeUnknown unknown error code (example) ErrCodeUnknown int = 600 // StatusCodeUnknown unknown HTTP status code (example) StatusCodeUnknown int = 600 )
Variables ¶
This section is empty.
Functions ¶
func FilterMap ¶ added in v0.1.12
func FilterMap(params *parameters.Params, filterOutFields []string) (filtered *parameters.Params)
FilterMap will filter the parameters and not log parameters with sensitive data. To add more parameters - see the if in the loop.
func FindString ¶ added in v0.0.10
FindString returns the index of the first instance of needle in the array or -1 if it could not be found
func GetAuthToken ¶ added in v0.0.23
GetAuthToken gets the stored authentication token from the request
func GetClientIPAddress ¶
GetClientIPAddress gets the client ip address
func GetCustomData ¶ added in v0.0.24
GetCustomData gets the stored custom data
func GetIPFromRequest ¶ added in v0.0.15
GetIPFromRequest gets the stored ip from the request if found
func GetParams ¶
GetParams gets the params from the http request (parsed once on log request) Helper method for the parameters package
func GetRequestID ¶ added in v0.0.15
GetRequestID gets the stored request id from the request
func JSONEncode ¶ added in v0.0.10
JSONEncode will encode only the allowed fields of the models
func JSONEncodeHierarchy ¶ added in v0.0.10
JSONEncodeHierarchy will execute JSONEncode for multiple nested objects
func NoCache ¶ added in v0.0.22
func NoCache(w http.ResponseWriter, req *http.Request)
NoCache is a simple piece of middleware that sets a number of HTTP headers to prevent a router (or subrouter) from being cached by an upstream proxy and/or client.
As per http://wiki.nginx.org/HttpProxyModule - NoCache sets:
Expires: Thu, 01 Jan 1970 00:00:00 UTC Cache-Control: no-cache, private, max-age=0 X-Accel-Expires: 0 Pragma: no-cache (for HTTP/1.0 proxies/clients)
func PermitParams ¶ added in v0.0.17
func PermitParams(params *parameters.Params, allowedKeys []string)
PermitParams will remove all keys that not allowed Helper method for the parameters package
func ReturnJSONEncode ¶ added in v0.0.12
func ReturnJSONEncode(w http.ResponseWriter, code int, e *json.Encoder, objects interface{}, allowed []string) (err error)
ReturnJSONEncode is a mixture of ReturnResponse and JSONEncode
func ReturnResponse ¶ added in v0.0.3
func ReturnResponse(w http.ResponseWriter, req *http.Request, code int, data interface{})
ReturnResponse helps return a status code and message to the end user
func SetAuthToken ¶ added in v0.0.23
SetAuthToken set the authentication token on the request
func SetCustomData ¶ added in v0.0.24
SetCustomData set the custom data / user profile / permissions / etc
func SetOnRequest ¶ added in v0.0.23
SetOnRequest will set the value on the request with the given key
func SnakeCase ¶ added in v0.0.10
SnakeCase takes a camelCaseWord and breaks it into a camel_case_word
func StandardHandlerToHandle ¶ added in v0.0.7
func StandardHandlerToHandle(next http.Handler) httprouter.Handle
StandardHandlerToHandle converts a standard middleware to Julien handle version
Types ¶
type APIError ¶
type APIError struct {
Code int `json:"code" url:"code"` // Associated error code
Data interface{} `json:"data" url:"data"` // Arbitrary data that is relevant
InternalMessage string `json:"-" url:"-"` // An internal message for engineers
IPAddress string `json:"ip_address" url:"ip_address"` // Current IP of user
Method string `json:"method" url:"method"` // Method requested (IE: POST)
PublicMessage string `json:"message" url:"message"` // Public error message
RequestGUID string `json:"request_guid" url:"request_guid"` // Unique Request ID for tracking
StatusCode int `json:"status_code" url:"status_code"` // Associated HTTP status code (should be in request as well)
URL string `json:"url" url:"url"` // Requesting URL
}
APIError is the enriched error message for API related errors
func ErrorFromRequest ¶ added in v0.0.16
func ErrorFromRequest(req *http.Request, internalMessage, publicMessage string, errorCode, statusCode int, data interface{}) *APIError
ErrorFromRequest gives an error without a response writer using the request
func ErrorFromResponse ¶ added in v0.0.16
func ErrorFromResponse(w *APIResponseWriter, internalMessage, publicMessage string, errorCode, statusCode int, data interface{}) *APIError
ErrorFromResponse generates a new error struct using CustomResponseWriter from LogRequest()
Example ¶
ExampleErrorFromResponse example using ErrorFromResponse()
w := setupTest()
err := ErrorFromResponse(w, "internal message", "public message", ErrCodeUnknown, StatusCodeUnknown, `{"something":"else"}`)
fmt.Println(err.Error())
Output: public message
func (*APIError) Error ¶
Error returns the string error message (only public message)
Example ¶
ExampleAPIError_Error example using Error()
w := setupTest()
err := ErrorFromResponse(w, "internal message", "public message", ErrCodeUnknown, StatusCodeUnknown, `{"something":"else"}`)
fmt.Println(err.Error())
Output: public message
func (*APIError) ErrorCode ¶
ErrorCode returns the error code
Example ¶
ExampleAPIError_ErrorCode example using ErrorCode()
w := setupTest()
err := ErrorFromResponse(w, "internal message", "public message", ErrCodeUnknown, StatusCodeUnknown, `{"something":"else"}`)
fmt.Println(err.ErrorCode())
Output: 600
func (*APIError) Internal ¶
Internal returns the string error message (only internal message)
Example ¶
ExampleAPIError_Internal example using Internal()
w := setupTest()
err := ErrorFromResponse(w, "internal message", "public message", ErrCodeUnknown, StatusCodeUnknown, `{"something":"else"}`)
fmt.Println(err.Internal())
Output: internal message
func (*APIError) JSON ¶
JSON returns the entire public version of the error message
Example ¶
ExampleAPIError_JSON example using JSON()
w := setupTest()
err := ErrorFromResponse(w, "internal message", "public message", ErrCodeUnknown, StatusCodeUnknown, `{"something":"else"}`)
str, _ := err.JSON()
fmt.Println(str)
Output: {"code":600,"data":"{\"something\":\"else\"}","ip_address":"127.0.0.1","method":"GET","message":"public message","request_guid":"unique-guid-per-user","status_code":600,"url":"/this/path"}
type APIResponseWriter ¶
type APIResponseWriter struct {
http.ResponseWriter
Buffer bytes.Buffer `json:"-" url:"-"`
CacheIdentifier []string `json:"cache_identifier" url:"cache_identifier"`
CacheTTL time.Duration `json:"cache_ttl" url:"cache_ttl"`
IPAddress string `json:"ip_address" url:"ip_address"`
Method string `json:"method" url:"method"`
NoWrite bool `json:"no_write" url:"no_write"`
RequestID string `json:"request_id" url:"request_id"`
Status int `json:"status" url:"status"`
URL string `json:"url" url:"url"`
UserAgent string `json:"user_agent" url:"user_agent"`
}
APIResponseWriter wraps the ResponseWriter and stores the status of the request. It is used by the LogRequest middleware
func (*APIResponseWriter) AddCacheIdentifier ¶
func (r *APIResponseWriter) AddCacheIdentifier(identifier string)
AddCacheIdentifier add cache identifier to the response writer
func (*APIResponseWriter) Header ¶
func (r *APIResponseWriter) Header() http.Header
Header returns the http.Header that will be written to the response
func (*APIResponseWriter) StatusCode ¶ added in v0.0.5
func (r *APIResponseWriter) StatusCode() int
StatusCode give a way to get the status code
func (*APIResponseWriter) Write ¶
func (r *APIResponseWriter) Write(data []byte) (int, error)
Write writes the data out to the client, if WriteHeader was not called, it will write status http.StatusOK (200)
func (*APIResponseWriter) WriteHeader ¶
func (r *APIResponseWriter) WriteHeader(status int)
WriteHeader will write the header to the client, setting the status code
type AllowedKeys ¶ added in v0.0.10
type AllowedKeys map[string]interface{}
AllowedKeys is for allowed keys
type InternalStack ¶ added in v0.0.18
type InternalStack struct {
// contains filtered or unexported fields
}
InternalStack internal stack type
func NewStack ¶ added in v0.0.6
func NewStack() *InternalStack
NewStack will create an InternalStack struct
func (*InternalStack) Use ¶ added in v0.0.18
func (s *InternalStack) Use(mw Middleware)
Use adds the middle ware to the list
func (*InternalStack) Wrap ¶ added in v0.0.18
func (s *InternalStack) Wrap(fn httprouter.Handle) httprouter.Handle
Wrap wraps the router
type Middleware ¶ added in v0.0.6
type Middleware func(httprouter.Handle) httprouter.Handle
Middleware is the Handle implementation
func StandardHandlerToMiddleware ¶ added in v0.0.8
func StandardHandlerToMiddleware(next http.Handler) Middleware
StandardHandlerToMiddleware converts a standard middleware to type Middleware
type Router ¶ added in v0.0.2
type Router struct {
AccessControlExposeHeaders string `json:"access_control_expose_headers" url:"access_control_expose_headers"` // Allow specific headers for cors
CrossOriginAllowCredentials bool `json:"cross_origin_allow_credentials" url:"cross_origin_allow_credentials"` // Allow credentials for BasicAuth()
CrossOriginAllowHeaders string `json:"cross_origin_allow_headers" url:"cross_origin_allow_headers"` // Allowed headers
CrossOriginAllowMethods string `json:"cross_origin_allow_methods" url:"cross_origin_allow_methods"` // Allowed methods
CrossOriginAllowOrigin string `json:"cross_origin_allow_origin" url:"cross_origin_allow_origin"` // Custom value for allow origin
CrossOriginAllowOriginAll bool `json:"cross_origin_allow_origin_all" url:"cross_origin_allow_origin_all"` // Allow all origins
CrossOriginEnabled bool `json:"cross_origin_enabled" url:"cross_origin_enabled"` // Enable or Disable CrossOrigin
FilterFields []string `json:"filter_fields" url:"filter_fields"` // Filter out protected fields from logging
HTTPRouter *httprouter.Router `json:"-" url:"-"` // J Schmidt's httprouter
SkipLoggingPaths []string `json:"skip_logging_paths" url:"skip_logging_paths"` // Skip logging on these paths (IE: /health)
}
Router is the configuration for the middleware service
func New ¶
func New() *Router
New returns a router middleware configuration to use for all future requests
func (*Router) BasicAuth ¶ added in v0.0.2
func (r *Router) BasicAuth(h httprouter.Handle, requiredUser, requiredPassword string, errorResponse interface{}) httprouter.Handle
BasicAuth wraps a request for Basic Authentication (RFC 2617)
func (*Router) Request ¶ added in v0.0.2
func (r *Router) Request(h httprouter.Handle) httprouter.Handle
Request will write the request to the logs before and after calling the handler
func (*Router) RequestNoLogging ¶ added in v0.0.2
func (r *Router) RequestNoLogging(h httprouter.Handle) httprouter.Handle
RequestNoLogging will just call the handler without any logging Used for API calls that do not require any logging overhead
func (*Router) SetCrossOriginHeaders ¶ added in v0.0.4
func (r *Router) SetCrossOriginHeaders(w http.ResponseWriter, req *http.Request, _ httprouter.Params)
SetCrossOriginHeaders sets the cross-origin headers if enabled todo: combine this method and the GlobalOPTIONS http.HandlerFunc() method
type Stack ¶ added in v0.0.6
type Stack interface {
/*
Adds a middleware to the InternalStack. MWs will be
called in the same order that they are added,
such that:
Use(Request ID Middleware)
Use(Request Timing Middleware)
would result in the request id middleware being
the outermost layer, called first, before the
timing middleware.
*/
// Use for adding new middlewares
Use(Middleware)
/*
Wraps a given handle with the current InternalStack
from the result of Use() calls.
*/
// Wrap wraps the router
Wrap(httprouter.Handle) httprouter.Handle
}
Stack is the interface for middleware
