Documentation ¶
Overview ¶
The render package helps manage HTTP request and response payloads.
Every well-designed, robust and maintainable Web Service / REST API also needs well-defined request and payloads. Together with the endpoint handler, the request and response payloads make up the contract between your server and the clients calling on it.
Typically in a REST API application, you will have data models (objects/structs) that hold lower-level runtime application state, and at time you need to assemble, decorate hide or transform the representation before responding to a client. That server output (response payload) structure, is likely the input structure to another handler on the server.
This is where render comes in - offering a few simple helpers and to provide a simple pattern for managing payload encoding and decoding.
The typical flow will look like the following: +-------------+ | REQUEST | // The in coming request from the client +-----+-------+ | V +-------------+ // Determined by the Content type of the body | decoders | // in order to decode the body into the passed +-----+-------+ // into the provided object/struct (decoders package) | V +-------------+ // Modify, assemble, decorate based models off the | Binder | // decoded object/struct from the decoder +-----+-------+ | V +-------------+ | Application | +-----+-------+ | V +-------------+ // Modify, assemble, decorate models to prepare | Render | // them to be encoded by the Responder +-----+-------+ | V +-------------+ // Determined by the Content-Type of the response | responders | // object, encode the provided object/struct (responders package) +-----+-------+ | V +-------------+ | RESPONSE | +-------------+
Index ¶
- Constants
- Variables
- func AllowedContentTypes(contentTypes ContentTypeSet) func(next http.Handler) http.Handler
- func Bind(r *http.Request, v Binder) error
- func ChannelEventStream(w http.ResponseWriter, r *http.Request, v interface{}) error
- func ErrLogToStdOut(err *ErrResponse)
- func Render(w http.ResponseWriter, r *http.Request, v Renderer) error
- func RenderList(w http.ResponseWriter, r *http.Request, l []Renderer) error
- func SetContentType(contentType ContentType) func(next http.Handler) http.Handler
- func SetDecoder(contentType ContentType, decoder decoders.Func)
- func SetResponder(contentType ContentType, responder responders.Func)
- func Status(r *http.Request, status int)
- func WithCtx(c *Controller) func(http.Handler) http.Handler
- type Binder
- type ContentType
- type ContentTypeSet
- func (set *ContentTypeSet) Has(contentType ContentType) bool
- func (set *ContentTypeSet) Next() bool
- func (set *ContentTypeSet) Reset()
- func (set *ContentTypeSet) String() string
- func (set *ContentTypeSet) StringHas(mediaType string) bool
- func (set *ContentTypeSet) Type() ContentType
- func (set *ContentTypeSet) Types() (types []ContentType)
- type Controller
- func (ctrl *Controller) Bind(r *http.Request, v Binder) error
- func (ctrl *Controller) Clone() *Controller
- func (ctrl *Controller) Render(w http.ResponseWriter, r *http.Request, v Renderer) error
- func (ctrl *Controller) RenderList(w http.ResponseWriter, r *http.Request, l []Renderer) error
- func (ctrl *Controller) SetDecoder(contentType ContentType, decoder decoders.Func) error
- func (ctrl *Controller) SetResponder(contentType ContentType, responder responders.Func) error
- func (ctrl *Controller) Status(r *http.Request, status int)
- func (ctrl *Controller) SupportedDecoders() *ContentTypeSet
- func (ctrl *Controller) SupportedResponders() *ContentTypeSet
- type ErrResponse
- type Interface
- type NilBinder
- type NilRender
- type Renderer
Constants ¶
const ( ContentTypeNone = ContentType("") ContentTypeDefault = ContentType("*/*") ContentTypeJSON = ContentType("application/json") ContentTypeData = ContentType("application/octet-stream") ContentTypeForm = ContentType("multipart/form-data") ContentTypeEventStream = ContentType("text/event-stream") ContentTypeHTML = ContentType("text/html") ContentTypePlainText = ContentType("text/plain") ContentTypeXML = ContentType("text/xml") )
ContentTypes that are commonly used
Variables ¶
var ( // ErrorHeaderPrefix is the prefix to add to the http headers for ErrResponse objects // // The following headers are created: // * ${ErrorHeaderPrefix}error-status // * ${ErrorHeaderPrefix}error-code // * ${ErrorHeaderPrefix}error-text // ErrorHeaderPrefix = "chi-render-" // GenErrorPin will generate a random 6 digit number that will be used to identify // the message in logs. Replace this if you want to change the way the error code // is generated GenErrorPin = func() string { var pin [errorCodeLength]byte _, _ = rand.Read(pin[:]) for i := range pin { pin[i] = (pin[i] % 10) + '0' } return string(pin[:]) } // ErrorLogTo is the default error logging function. // // If you want all your ErrResponse based errors to log when // they are render be sure to set this variable. Once can easily // set it in an Init function: // // e.g. // // func init(){ // render.ErrorHeaderPrefix = "my-prefix-" // render.ErrorLogTo = render.ErrLogToStdOut // } // ErrorLogTo func(*ErrResponse) )
var (
ContentTypeCtxKey = helpers.ContentTypeCtxKey
)
var ( // ErrControllerIsNil will be returned by methods that require the Controller object // to be not nil ErrControllerIsNil = errors.New("controller is nil") )
Functions ¶
func AllowedContentTypes ¶ added in v1.1.0
func AllowedContentTypes(contentTypes ContentTypeSet) func(next http.Handler) http.Handler
func ChannelEventStream ¶ added in v1.1.0
func ChannelEventStream(w http.ResponseWriter, r *http.Request, v interface{}) error
func ErrLogToStdOut ¶ added in v1.1.1
func ErrLogToStdOut(err *ErrResponse)
ErrLogToStdOut can be used to use go log to log out the error when it is rendered
func RenderList ¶
RenderList renders a slice of payloads and responds to the client request.
func SetContentType ¶
func SetContentType(contentType ContentType) func(next http.Handler) http.Handler
SetContentType is a middleware that forces response Content-Type.
func SetDecoder ¶ added in v1.1.0
func SetDecoder(contentType ContentType, decoder decoders.Func)
SetDecoder will set the decoder for the given content type. Use a nil DecodeFunc to unset a content type
func SetResponder ¶ added in v1.1.0
func SetResponder(contentType ContentType, responder responders.Func)
SetResponder will set the responder for the given content type. Use a nil RespondFunc to unset a content type
Types ¶
type Binder ¶
type Binder interface { // Binder should be used to recompose the original the data model object. // The Binder function is called after the decoders is called so the body // of the http.Request object will be spent. Bind(r *http.Request) error }
Binder interface for managing request payloads.
type ContentType ¶
type ContentType string
ContentType is an enumeration of common HTTP content types.
func ContentTypeFromString ¶ added in v1.1.0
func ContentTypeFromString(mediaType string) (ContentType, error)
ContentTypeFromString will call mime.ParseMediaType to get the content type out
func GetContentType ¶
func GetContentType(str string) (ContentType, error)
GetContentType returns the base mimetype from the string. This uses mime.ParseMediaType to actually parse the string.
func GetRequestContentType ¶
func GetRequestContentType(r *http.Request, dflt ContentType) ContentType
GetRequestContentType is a helper function that returns ContentType based on context or "content-Type" request header.
func (ContentType) Is ¶ added in v1.1.0
func (contentType ContentType) Is(mimeType string) bool
Is the content type a match for the given mime type
func (ContentType) String ¶ added in v1.1.0
func (contentType ContentType) String() string
type ContentTypeSet ¶ added in v1.1.0
type ContentTypeSet struct {
// contains filtered or unexported fields
}
ContentTypeSet is a ordered set of content types
func GetAcceptedContentType ¶
func GetAcceptedContentType(r *http.Request) *ContentTypeSet
GetAcceptedContentType is a helper function that returns a set of ContentTypes based on context or "Accept" request header.
func NewContentTypeSet ¶ added in v1.1.0
func NewContentTypeSet(types ...string) *ContentTypeSet
NewContentTypeSet returns a new set of ContentTypes based on the set of strings passed in. mime.ParseMediaType is used to parse each string. Empty strings and strings that do not parse are ignored.
func SetOfContentTypes ¶ added in v1.1.0
func SetOfContentTypes(types ...ContentType) *ContentTypeSet
SetOfContentTypes returns a set of the given ContentTypes
func SupportedDecoders ¶ added in v1.1.0
func SupportedDecoders() *ContentTypeSet
SupportedDecoders returns a ContentTypeSet of the configured Content types with decoders
func SupportedResponders ¶ added in v1.1.0
func SupportedResponders() *ContentTypeSet
SupportedResponders returns a ContentTypeSet of the configured Content types with responders
func (*ContentTypeSet) Has ¶ added in v1.1.0
func (set *ContentTypeSet) Has(contentType ContentType) bool
Has checks to see if the set contains the content type
func (*ContentTypeSet) Next ¶ added in v1.1.0
func (set *ContentTypeSet) Next() bool
Next returns if there is another content type waiting, and if there is advance to it
func (*ContentTypeSet) Reset ¶ added in v1.1.0
func (set *ContentTypeSet) Reset()
Reset to the start of the content types
func (*ContentTypeSet) String ¶ added in v1.1.0
func (set *ContentTypeSet) String() string
func (*ContentTypeSet) StringHas ¶ added in v1.1.0
func (set *ContentTypeSet) StringHas(mediaType string) bool
StringHas is like Has but first parses the contentType out if the mediaType using mime.ParseMediaType; parse errors return false
func (*ContentTypeSet) Type ¶ added in v1.1.0
func (set *ContentTypeSet) Type() ContentType
Type returns the current ContentType of the set
func (*ContentTypeSet) Types ¶ added in v1.1.0
func (set *ContentTypeSet) Types() (types []ContentType)
Types returns a copy of the content types in order specified
type Controller ¶ added in v1.1.0
type Controller struct { // If no content type matches, this content type will be used. DefaultRequest ContentType // If no Accept header match, this content type will be used to render the object DefaultResponse ContentType // contains filtered or unexported fields }
Controller is responsible for managing the respond types that are available
func CloneDefault ¶ added in v1.1.0
func CloneDefault() *Controller
CloneDefault will return a Clone of the default controller
func FromContext ¶ added in v1.1.0
func FromContext(r *http.Request) *Controller
FromContext will retrieve the render object from the context
func (*Controller) Bind ¶ added in v1.1.0
func (ctrl *Controller) Bind(r *http.Request, v Binder) error
Bind decodes a request body and executes the Binder method of the payload structure.
func (*Controller) Clone ¶ added in v1.1.0
func (ctrl *Controller) Clone() *Controller
Clone will return a deep copy version of the controller if ctrl is nil a clone of the default system controller will be returned instead
func (*Controller) Render ¶ added in v1.1.0
func (ctrl *Controller) Render(w http.ResponseWriter, r *http.Request, v Renderer) error
Render renders a single payload and respond to the client request.
func (*Controller) RenderList ¶ added in v1.1.0
func (ctrl *Controller) RenderList(w http.ResponseWriter, r *http.Request, l []Renderer) error
RenderList renders a slice of payloads and responds to the client request.
func (*Controller) SetDecoder ¶ added in v1.1.0
func (ctrl *Controller) SetDecoder(contentType ContentType, decoder decoders.Func) error
SetDecoder will set the decoder for the given content type. Use a nil DecodeFunc to unset a content type Only error this function will return is ErrControllerIsNil; is returned if the Controller object is nil.
func (*Controller) SetResponder ¶ added in v1.1.0
func (ctrl *Controller) SetResponder(contentType ContentType, responder responders.Func) error
SetResponder will set the responder for the given content type. Use a nil RespondFunc to unset a content type Only error this function will return is ErrControllerIsNil; is returned if the Controller object is nil.
func (*Controller) Status ¶ added in v1.1.0
func (ctrl *Controller) Status(r *http.Request, status int)
Status sets a HTTP response status code hint into request context at any point during the request life-cycle. Before the Responder sends its response header it will check the StatusCtxKey
func (*Controller) SupportedDecoders ¶ added in v1.1.0
func (ctrl *Controller) SupportedDecoders() *ContentTypeSet
SupportedDecoders returns a ContentTypeSet of the configured Content types with decoders
func (*Controller) SupportedResponders ¶ added in v1.1.0
func (ctrl *Controller) SupportedResponders() *ContentTypeSet
SupportedResponders returns a ContentTypeSet of the configured Content types with responders
type ErrResponse ¶ added in v1.1.1
type ErrResponse struct { Err error `json:"-"` // low-level runtime error StatusCode int `json:"-"` // http response status code StatusText string `json:"status"` // user-level status message ErrorCode string `json:"code"` // application-specific error code ErrorText string `json:"error,omitempty"` // application-level error message, for debugging // If you want to print out the issue set this the default ErrLogTo LogTo func(*ErrResponse) `json:"-"` }
ErrResponse renderer type for handling all sorts of errors.
In the best case scenario, the excellent github.com/pkg/errors package helps reveal information on the error, setting it on Err, and in the Render() method, using it to set the application-specific error code in AppCode.
func (*ErrResponse) Render ¶ added in v1.1.1
func (err *ErrResponse) Render(w http.ResponseWriter, r *http.Request) error
Render will be called by the render to modify the ErrResponse object before it gets encoded by the Responders
type Interface ¶ added in v1.1.0
type Interface interface { Bind(r *http.Request, v Binder) error Render(w http.ResponseWriter, r *http.Request, v Renderer) error RenderList(w http.ResponseWriter, r *http.Request, l []Renderer) error }
Interface defines what a render controller should behave like
type NilBinder ¶ added in v1.1.1
type NilBinder struct{}
NilBinder is an empty struct that can be embedded to provide a simple way to return a struct into a Bind-able object
type NilRender ¶ added in v1.1.1
type NilRender struct{}
NilRender is an empty struct that can be embedded to provide a simple way to turn a struct into a Render-able object
type Renderer ¶
type Renderer interface { // Render should modify the object so that it is in the correct configuration // for the responders to render the object. One can interrogate the request object // or if necessary modify the headers in the ResponseWriter object. // The Render method should not write to the body fo the ResponseWriter object, // the at is reserved for the responder objects. Render(w http.ResponseWriter, r *http.Request) error }
Renderer interface for managing response payloads.