Documentation
¶
Overview ¶
Package rsvp is a Go web framework built around content negotiation.
The framework automatically negotiates response format based on the Accept header, supporting JSON, XML, HTML, plain text, CSV, binary, Gob, and MessagePack (using -tags=rsvp_msgpack). This content negotiation extends to ALL responses, including redirects, allowing you to provide rich feedback in many contexts.
The Accept header should be expected to be used as standardized; weighting is supported. If an acceptable fallback is not reached, a 406 Not Acceptable will be returned, and the Content-Type and body will be set as if Accept: */* had been sent.
This makes rsvp particularly well-suited for APIs that serve multiple clients (browsers, mobile apps, CLI tools) and for taking advantage of principles such as REST and progressive enhancement.
Index ¶
- Constants
- Variables
- func AdaptHandler(config Config, next Handler) http.Handler
- func AdaptHandlerFunc(cfg Config, next HandlerFunc) http.HandlerFunc
- func Write(w io.Writer, cfg Config, wh http.Header, r *http.Request, handler HandlerFunc) (int, error)
- func WriteHandler(cfg Config, rw http.ResponseWriter, r *http.Request, handler HandlerFunc) error
- func WriteResponse(status int, w http.ResponseWriter, r io.Reader) error
- type Body
- func (res *Body) MediaTypes(cfg Config) iter.Seq[string]
- func (r Body) StatusAccepted() Body
- func (r Body) StatusBadRequest() Body
- func (r Body) StatusConflict() Body
- func (r Body) StatusCreated(location string) Body
- func (r Body) StatusForbidden() Body
- func (r Body) StatusFound(location string) Body
- func (r Body) StatusGone() Body
- func (r Body) StatusInternalServerError() Body
- func (r Body) StatusMethodNotAllowed() Body
- func (r Body) StatusMovedPermanently(location string) Body
- func (r Body) StatusNoContent() Body
- func (r Body) StatusNotAcceptable() Body
- func (r Body) StatusNotFound() Body
- func (r Body) StatusNotImplemented() Body
- func (r Body) StatusNotModified() Body
- func (r Body) StatusPermanentRedirect(location string) Body
- func (r Body) StatusSeeOther(location string) Body
- func (r Body) StatusServiceUnavailable() Body
- func (r Body) StatusTemporaryRedirect(location string) Body
- func (r Body) StatusTooManyRequests() Body
- func (r Body) StatusUnauthorized() Body
- func (r Body) StatusUnprocessableEntity() Body
- type Config
- type Csv
- type Handler
- type HandlerFunc
- type ResponseWriter
Constants ¶
const ( SupportedMediaTypePlaintext string = "text/plain" SupportedMediaTypeHtml string = "text/html" SupportedMediaTypeCsv string = "text/csv" SupportedMediaTypeBytes string = "application/octet-stream" SupportedMediaTypeJson string = "application/json" SupportedMediaTypeXml string = "application/xml" SupportedMediaTypeGob string = "application/vnd.golang.gob" )
Variables ¶
var ErrFailedToMatchHtmlTemplate = errors.New("TemplateName was set, but it failed to match within HtmlTemplate")
var ErrFailedToMatchTextTemplate = errors.New("TemplateName was set, but it failed to match within TextTemplate")
Functions ¶
func AdaptHandler ¶
AdaptHandler wraps a Handler as an http.Handler with the given config.
This is the primary entrypoint to using rsvp.
func AdaptHandlerFunc ¶
func AdaptHandlerFunc(cfg Config, next HandlerFunc) http.HandlerFunc
AdaptHandlerFunc wraps a HandlerFunc as an http.HandlerFunc with the given config.
This is the primary entrypoint to using rsvp.
func Write ¶
func Write(w io.Writer, cfg Config, wh http.Header, r *http.Request, handler HandlerFunc) (int, error)
Write the result of handler to w. Returns an HTTP status code, and may write headers to wh.
NOTE: This function is for advanced lower-level use cases.
This function, alongside WriteResponse, should be used to wrap Handler in middleware that requires _write_ access to http.ResponseWriter. [Handle] and [HandleFunc] may be used for simpler standard middleware that does not write to http.ResponseWriter.
See this test for an example: https://github.com/Teajey/rsvp/blob/main/middleware_test.go
func WriteHandler ¶
func WriteHandler(cfg Config, rw http.ResponseWriter, r *http.Request, handler HandlerFunc) error
WriteHandler writes the result of handler to rw according to cfg.
NOTE: This function is for advanced lower-level use cases.
func WriteResponse ¶
WriteResponse calls w.WriteHeader(status) and copies r to w.
NOTE: This function is for advanced lower-level use cases.
This function, alongside Write, should be used to wrap Handler in middleware that requires _write_ access to http.ResponseWriter. AdaptHandler and AdaptHandlerFunc may be used for simpler standard middleware that does not write to http.ResponseWriter.
See this test for an example: https://github.com/Teajey/rsvp/blob/main/middleware_test.go
Types ¶
type Body ¶
type Body struct {
// Data is the raw data of the response payload to be rendered.
//
// IMPORTANT: A nil Data renders as JSON "null\n", not an empty response.
// Use Data("") for a blank text/plain response body, or [Blank] for a blank response with no Content-Type.
Data any
// TemplateName sets the template that this Body may attempt to select from
// [Config.HtmlTemplate] or [Config.TextTemplate],
//
// [ResponseWriter.DefaultTemplateName] may also be used to avoiding setting TemplateName multiple times on every return point of a single handler.
//
// It is not an error if a template is not found for one of the two templates; other formats will be attempted.
TemplateName string
// contains filtered or unexported fields
}
Body represents the content body of an HTTP response.
By default, it represents a 200 OK response. The Body.Status* methods (e.g. Body.StatusFound) may be used to set a non-200 status.
func Blank ¶
func Blank() Body
Blank will render as a blank response with no Content-Type.
Status 200 by default.
func Data ¶
Data is a convenience function equivalent to instantiating Body{Data: data}
IMPORTANT: nil Data renders as JSON "null\n", not an empty response. Use Data("") for a blank text/plain response body, or Blank for a blank response with no Content-Type.
func (*Body) MediaTypes ¶
MediaTypes returns the sequence of media types (e.g. text/plain) in the order that this Body will propose.
The order generally follows this pattern:
- Type-specific (Html wrapper, string, bytes)
- Generic structured (JSON, XML)
- Interface implementations (CSV)
- Template-based (HTML template, text template)
- Golang-native fallback (Gob)
func (Body) StatusAccepted ¶
StatusAccepted sets the response as 202 Accepted.
It indicates that the request has been accepted for processing, but the processing has not been completed.
func (Body) StatusBadRequest ¶
StatusBadRequest sets the response as 400 Bad Request.
It indicates that the server cannot process the request due to client error, such as malformed request syntax or invalid request parameters.
func (Body) StatusConflict ¶
StatusConflict sets the response as 409 Conflict.
It indicates that the request conflicts with the current state of the server, such as attempting to create a duplicate resource.
func (Body) StatusCreated ¶
StatusCreated sets the response as 201 Created and sets the Location header.
It indicates that a new resource has been successfully created at the given location.
func (Body) StatusForbidden ¶
StatusForbidden sets the response as 403 Forbidden.
It indicates that the server understood the request but refuses to authorize it. Unlike 401, authenticating will make no difference.
func (Body) StatusFound ¶
StatusFound sets the response as 302 Found and sets the Location header.
It indicates that the requested resource has been temporarily moved to the given location.
func (Body) StatusGone ¶
StatusGone sets the response as 410 Gone.
It indicates that the requested resource is no longer available and will not be available again. This is a stronger statement than 404 Not Found.
func (Body) StatusInternalServerError ¶
StatusInternalServerError sets the response as 500 Internal Server Error.
It indicates that the server encountered an unexpected condition that prevented it from fulfilling the request.
func (Body) StatusMethodNotAllowed ¶
StatusMethodNotAllowed sets the response as 405 Method Not Allowed.
It indicates that the request method is known by the server but is not supported by the target resource.
func (Body) StatusMovedPermanently ¶
StatusMovedPermanently sets the response as 301 Moved Permanently and sets the Location header.
Moved Permanently is intended for GET requests.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Redirections#permanent_redirections
func (Body) StatusNoContent ¶
StatusNoContent sets the response as 204 No Content.
It indicates that the request was successful but there is no content to return. Commonly used for DELETE operations or updates with no response body.
func (Body) StatusNotAcceptable ¶
StatusNotAcceptable sets the response as 406 Not Acceptable.
It indicates that the server cannot produce a response matching the list of acceptable values defined in the request's proactive content negotiation headers.
func (Body) StatusNotFound ¶
StatusNotFound sets the response as 404 Not Found.
It indicates that the server cannot find the requested resource.
func (Body) StatusNotImplemented ¶
StatusNotImplemented sets the response as 501 Not Implemented.
It indicates that the server does not support the functionality required to fulfill the request.
func (Body) StatusNotModified ¶
StatusNotModified sets the response as 304 Not Modified.
It indicates that the resource has not been modified since the version specified by the request headers. Used for conditional requests and caching.
func (Body) StatusPermanentRedirect ¶
StatusPermanentRedirect sets the response as 308 Permanent Redirect and sets the Location header.
Permanent Redirect is intended for non-GET requests.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Redirections#permanent_redirections
func (Body) StatusSeeOther ¶
StatusSeeOther sets the response as 303 See Other and sets the Location header.
See Other is used for redirection in response to POST requests.
func (Body) StatusServiceUnavailable ¶
StatusServiceUnavailable sets the response as 503 Service Unavailable.
It indicates that the server is currently unable to handle the request due to temporary overload or scheduled maintenance.
func (Body) StatusTemporaryRedirect ¶
StatusTemporaryRedirect sets the response as 307 Temporary Redirect and sets the Location header.
Temporary Redirect is like 302 Found but guarantees that the HTTP method will not be changed when the redirected request is made.
func (Body) StatusTooManyRequests ¶
StatusTooManyRequests sets the response as 429 Too Many Requests.
It indicates that the user has sent too many requests in a given amount of time. Used for rate limiting.
func (Body) StatusUnauthorized ¶
StatusUnauthorized sets the response as 401 Unauthorized.
It indicates that authentication is required and has failed or has not been provided.
func (Body) StatusUnprocessableEntity ¶
StatusUnprocessableEntity sets the response as 422 Unprocessable Entity.
It indicates that the request was well-formed but was unable to be followed due to semantic errors, such as validation failures.
type Config ¶
type Config struct {
// [Body.Data] may be passed to this template as data if content negotiation resolves to text/html and [Body.TemplateName] matches via [html.Template.Lookup].
//
// If both HtmlTemplate and TextTemplate match [Body.TemplateName], HtmlTemplate takes precedence.
HtmlTemplate *html.Template
// [Body.Data] may be passed to this template as data if content negotiation resolves to text/plain and [Body.TemplateName] matches via [text.Template.Lookup].
//
// If both HtmlTemplate and TextTemplate match [Body.TemplateName], HtmlTemplate takes precedence.
TextTemplate *text.Template
// JsonPrefix is used to set [json.Encoder.SetIndent]
JsonPrefix string
// JsonIndent is used to set [json.Encoder.SetIndent]
JsonIndent string
// XmlPrefix is used to set [xml.Encoder.Indent]
XmlPrefix string
// XmlIndent is used to set [xml.Encoder.Indent]
XmlIndent string
}
Settings for writing the rsvp.Body
type Csv ¶
type Csv interface {
// MarshalCsv will be called if the Accept header contains text/csv and it is matched, or the URL path ends with .csv
MarshalCsv(w *csv.Writer) error
}
Csv is used to provide rsvp with a way to render your type as text/csv.
type Handler ¶
type Handler interface {
ServeHTTP(w ResponseWriter, r *http.Request) Body
}
Handler is rsvp's counterpart to http.Handler.
type HandlerFunc ¶
type HandlerFunc func(w ResponseWriter, r *http.Request) Body
HandlerFunc is a counterpart to http.HandlerFunc.
func (HandlerFunc) ServeHTTP ¶
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *http.Request) Body
type ResponseWriter ¶
type ResponseWriter interface {
// Header is equivalent to [http.ResponseWriter.Header]
Header() http.Header
// DefaultTemplateName is used to associate a default template name with the current handler.
//
// It may be overridden by [Body.TemplateName].
//
// The intended use case for this method is to call it at the top of an [HandlerFunc] so that the TemplateName does not need to be set exhaustively on every instance of [Body] that the handler might return.
DefaultTemplateName(name string)
}
ResponseWriter handles metadata and configuration of the response. It bears its "Writer" name mostly for the sake of keeping rsvp.Handler similar to http.Handler.
Its underlying type has a `write` function, but it is not available here because it is controlled indirectly by the Body value that Handler provides.
If you need access to http.ResponseWriter, especially for middleware, you should follow the example of [HandleFunc]'s source code for how to operate rsvp at a lower level from within an http.Handler.