Documentation ¶
Overview ¶
Package resp provides a high-level API for responding to HTTP requests.
The core of the package revolves around the interplay between a Responder, which ought to be configured for broad contexts (i.e., application-wide), and a Response, which lives at the http.Handler level.
Within a handler, a Responder constructs a Response and finally executes a response in one of these ways: - rendering HTML templates - rendering JSON data - redirecting - writing error messages/codes
Responders and Responses draw upon configuration happening through functional options. To avoid needless error throwing, both may silently ignore options that are irrelevant or would put them in invalid states. In some cases, a Responder may emit logs warning of incorrect usage, enabling a developer to remediate these mistakes within their workflow.
However, some incorrect use cannot be fixed and all of the forms of response made available by a Responder (e.g., Html, Json, Redirect) can return meaningful errors.
The Responder is responsible for providing any data a Response may need to do its work correctly. Notably, a Responder contains data on default templates, keys used for an *http.Request.Context, the web app's root URL and so forth. ResponderOptFns carry out configuring a Responder and are unlikely to be used within a handler. Instead, it is expected these feature in a web app's router setup steps.
Index ¶
- Variables
- func WithAdditionalScriptsTemplate(fp string) func(*Responder)
- func WithAuthTemplate(fp string) func(*Responder)
- func WithContactErrMsg(msg string) func(*Responder)
- func WithErrTemplate(fp string) func(*Responder)
- func WithLogger(log logger.Logger) func(*Responder)
- func WithParser(p *template.Parser) func(*Responder)
- func WithRootUrl(u string) func(*Responder)
- func WithUnauthTemplate(fp string) func(*Responder)
- func WithVueScriptsTemplate(fp string) func(*Responder)
- func WithVueTemplate(fp string) func(*Responder)
- type Fn
- func Authed() Fn
- func Code(c int) Fn
- func CurrentUser(u any) Fn
- func Data(d any) Fn
- func Err(e error) Fn
- func Flash(flash session.Flash) Fn
- func GenericErr(e error) Fn
- func Params(pairs map[string]string) Fn
- func Success(msg string) Fn
- func Tmpls(fps ...string) Fn
- func ToRoot() Fn
- func Toolbox(toolbox trails.Toolbox) Fn
- func Unauthed() Fn
- func Url(u string) Fn
- func Vue(entry string) Fn
- func Warn(msg string) Fn
- type Responder
- func (doer Responder) CurrentUser(ctx context.Context) (any, error)
- func (doer *Responder) Err(w http.ResponseWriter, r *http.Request, err error, opts ...Fn)
- func (doer *Responder) Html(w http.ResponseWriter, r *http.Request, opts ...Fn) error
- func (doer *Responder) Json(w http.ResponseWriter, r *http.Request, opts ...Fn) error
- func (doer *Responder) Redirect(w http.ResponseWriter, r *http.Request, opts ...Fn) error
- func (doer Responder) Session(ctx context.Context) (session.Session, error)
- type ResponderOptFn
- type Response
Constants ¶
This section is empty.
Variables ¶
Functions ¶
func WithAdditionalScriptsTemplate ¶ added in v0.6.1
WithAdditionalScriptsTemplate sets the template identified by the filepath to use for rendering alongside Authed and Unauthed templates.
Authed and Unauthed requires this option.
func WithAuthTemplate ¶
WithAuthTemplate sets the template identified by the filepath to use for rendering when a user is authenticated.
Authed requires this option.
func WithContactErrMsg ¶
WithContactErrMsg sets the error message to use for error Flashes.
We recommend using session.ContactUsErr as a template.
func WithErrTemplate ¶ added in v0.6.0
WithErrTemplate sets the template identified by the filepath to use for rendering when an unexpected, unhandled error occurs while
func WithLogger ¶
WithLogger sets the provided implementation of Logger in order to log all statements through it.
If no Logger is provided through this option, a defaultLogger will be configured.
func WithParser ¶
WithParser sets the provided implementation of template.Parser to use for parsing HTML templates.
func WithRootUrl ¶
WithRootUrl sets the provided URL after parsing it into a *url.URL to use for rendering and redirecting
NOTE: If u fails parsing by url.ParseRequestURI, the root URL becomes https://example.com
func WithUnauthTemplate ¶
WithUnauthTemplate sets the template identified by the filepath to use for rendering when a user is not authenticated.
Unauthed requires this option.
func WithVueScriptsTemplate ¶ added in v0.6.1
WithVueTemplate sets the template identified by the filepath to use for rendering additional scripts within a Vue client application.
Vue requires this option.
func WithVueTemplate ¶
WithVueTemplate sets the template identified by the filepath to use for rendering a Vue client application.
Vue requires this option.
Types ¶
type Fn ¶
A Fn is a functional option that mutates the state of the Response.
func Authed ¶
func Authed() Fn
Authed prepends all templates with the base authenticated template and adds resp.user from the session.
If no user can be retrieved from the session, it is assumed a user is not logged in and returns ErrNoUser.
If WithAuthTemplate was not called setting up the Responder, ErrBadConfig returns.
func CurrentUser ¶ added in v0.4.1
CurrentUser stores the user in the *Response.
Used with Responder.Html and Responder.Json. When used with Json, the user is assigned to the "currentUser" key.
func Data ¶
Data stores the provided value for writing to the client.
Used with Responder.Html and Responder.Json.
func GenericErr ¶
GenericErr combines Err() and Flash() to log the passed in error and set a generic error flash in the session using either the string set by WithContactErrMsg or session.DefaultErrMsg.
func Params ¶ added in v0.3.15
Params adds the query parameters to the response's URL. Params appends to rather than overwrite other query parameters.
Used with Responder.Redirect.
func Success ¶
Success sets the status OK to http.StatusOK and sets a session.FlashSuccess flash in the session with the passed in msg.
Used with Responder.Html.
func Toolbox ¶ added in v0.6.1
Toolbox includes the toolbox in the data to be rendered. Toolbox should be called after Data. Toolbox only supports including the provided toolbox in the data if it is map[string]any.
Multiple calls to Toolbox results in merging the trails.Tools together.
func Unauthed ¶
func Unauthed() Fn
Unauthed prepends all templates with the base unauthenticated template. If the first template is the base authenticated template, this overwrites it.
If WithUnauthTemplate was not called setting up the Responder, ErrBadConfig returns.
func Url ¶
Url parses raw the URL string and sets it in the *Response if successful.
Used with Responder.Redirect.
func Vue ¶
Vue structures the provided data alongside default values according to a default schema.
Here's the schema:
{ "entry": entry, "props": { "initialProps": { "baseURL": d.rootUrl, "currentUser": r.user, }, ...key-value pairs set by Data ...key-value pairs set using trails.AppPropsKey }, ...key-value pairs set by Data }
Calls to Data are merged into the required schema in the following way.
At it's simplest, for example, Data(map[string]any{"myProp": "Hello, World"}), will produce:
{ "entry": entry, "props": { "myProp": "Hello, World", "initialProps": { "baseURL": d.rootUrl, "currentUser": r.user, } } }
If the type passed into Data is not map[string]any, Data(myStruct{}), the value is placed under another "props" key, producing:
{ "entry": entry, "props": { "props": myStruct{}, "initialProps": { "baseURL": d.rootUrl, "currentUser": r.user, }, } }
Finally, if values need to be present to template rendering under a specific key, and properties need to be passed in as well, include a map[string]any the "initialProps" key and the two maps will be merged.
Here's how that's done:
data := map[string]any{ "keyForMyTmpl": true, "props": map[string]any{ "myProp": "Hello, World" }, }
Html(Data(data), Vue(entry))
will produce:
{ "entry": entry, "keyForMyTmpl": true "props: { "myProp": "Hello, World", "initialProps": { "baseURL": d.rootUrl, "currentUser": r.user, }, }, }
It is not required to set any keys for pulling additional values out of the *http.Request.Context.
type Responder ¶
type Responder struct {
// contains filtered or unexported fields
}
Responder maintains reusable pieces for responding to HTTP requests. It exposes many common methods for writing structured data as an HTTP response. These are the forms of response Responder can execute:
Html Json Redirect
Most oftentimes, setting up a single instance of a Responder suffices for an application. Meaning, one needs only application-wide configuration of how HTTP responses should look. Our suggestion does not exclude creating diverse Responders for non-overlapping segments of an application.
When handling a specific HTTP request, calling code supplies additional data, structure, and so forth through Fn functions. While one can create functions of the same type, the Responder and Response structs do not expose much - if anything - to interact with.
func NewResponder ¶
func NewResponder(opts ...ResponderOptFn) *Responder
NewResponder constructs a *Responder using the ResponderOptFns passed in.
TODO(dlk): make setting root url required arg? + cannot redirect in err state w/o
func (Responder) CurrentUser ¶
CurrentUser retrieves the user set in the context.
If WithUserSessionKey was not called setting up the Responder or the context.Context has no value for that key, ErrNotFound returns.
func (*Responder) Err ¶
Err wraps http.Error(), logging the error causing the failure state.
Use in exceptional circumstances when no Redirect or Html can occur.
func (*Responder) Html ¶
Html composes together HTML templates set in *Responder and configured by Authed, Unauthed, Tmpls and other such calls.
func (*Responder) Json ¶
Json responds with data in JSON format, collating it from User(), Data() and setting appropriate headers.
When standard 2xx codes are supplied, the JSON schema will look like this:
{ "currentUser": {}, "data": {} }
Otherwise, "currentUser" is elided.
User() calls populate "currentUser" Data() calls populate "data"
func (*Responder) Redirect ¶
Redirect calls http.Redirect, given Url() set the redirect destination. If Url() is not passed in opts, then ToRoot() sets the redirect destination.
The default response status code is 302.
If Code() set the status code to something other than standard redirect 3xx statuses, Redirect overwrites the status code with an appropriate 3xx status code.
type ResponderOptFn ¶
type ResponderOptFn func(*Responder)
A ResponderOptFn mutates the provided *Responder in some way. A ResponderOptFn is used when constructing a new Responder.