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 FindString(needle string, haystack []string) int
- func GetClientIPAddress(req *http.Request) string
- func GetIPFromRequest(req *http.Request) (ip string, ok bool)
- func GetParams(req *http.Request) (params url.Values, ok bool)
- 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 NewStack() *stack
- 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 SnakeCase(str string) string
- func StandardHandlerToHandle(next http.Handler) httprouter.Handle
- type APIError
- type APIResponseWriter
- type AllowedKeys
- 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 )
Variables ¶
This section is empty.
Functions ¶
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 GetClientIPAddress ¶
GetClientIPAddress gets the client ip address
func GetIPFromRequest ¶ added in v0.0.15
GetIPFromRequest gets the stored ip from the request if found
func GetRequestID ¶ added in v0.0.15
GetRequestID gets the stored request id from the request
func JSONEncode ¶ added in v0.0.10
JSONEncodeModels 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 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 SnakeCase ¶ added in v0.0.10
SnakeCase takes a camelCaseWord and breaks it into 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:"-"` // 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
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 string, publicMessage string, errorCode 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 string, publicMessage string, errorCode int, data interface{}) *APIError
ErrorFromResponse generates a new error struct using CustomResponseWriter from LogRequest()
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, `{"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, `{"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, `{"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, `{"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","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 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
StandardHandlerToHandle converts a standard middleware to type Middleware
type Router ¶ added in v0.0.2
type Router struct {
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
HTTPRouter *httprouter.Router `json:"-" url:"-"` // J Schmidt's httprouter
}
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
type Stack ¶ added in v0.0.6
type Stack interface {
/*
Adds a middleware to the stack. 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 stack
from the result of Use() calls.
*/
// Wrap wraps the router
Wrap(httprouter.Handle) httprouter.Handle
}
Stack is the interface for middleware