Documentation
¶
Overview ¶
Package httpapi provides assistance for servers that implement a JSON Web API. It has no pretensions to be a framework: it is intended to work with the standard library HTTP handlers. The goal is to provide simple primitives for reading input from HTTP requests and writing output to the HTTP response writer.
The package supports compressing responses if the client can support it. It also provides non-standard support for clients compressing the body of requests. See the ReadRequest function for more details.
The WriteError function provides a simple, consistent way to send error messages to HTTP clients. It has some sensible defaults for the format and handling of JSON error messages, but can be customized. See the writeerror subdirectory package for details.
Example ¶
package main import ( "net/http" "github.com/gorilla/mux" "github.com/jjeffery/httpapi" ) func main() { r := mux.NewRouter() r.Path("/api/something").Methods("POST").HandlerFunc(postHandler) r.Path("/api/something").Methods("GET").HandlerFunc(getHandler) http.ListenAndServe(":8080", r) } // postHandler handles POST requests func postHandler(w http.ResponseWriter, r *http.Request) { // unmarshal input from request var input PostSomethingInput if err := httpapi.ReadRequest(r, &input); err != nil { httpapi.WriteError(w, r, err) return } output, err := postSomething(r.Context(), &input) if err != nil { httpapi.WriteError(w, r, err) return } httpapi.WriteResponse(w, r, output) } // getHandler extracts the input from the query strings of the HTTP request. func getHandler(w http.ResponseWriter, r *http.Request) { query := httpapi.Query(r) input := GetSomethingInput{ Search: query.GetString("q"), Since: query.GetTime("since"), Limit: query.GetInt("limit"), Offset: query.GetInt("offset"), } // validate once after all query string parameters have been read if err := query.Err(); err != nil { httpapi.WriteResponse(w, r, err) return } output, err := getSomething(r.Context(), &input) if err != nil { httpapi.WriteError(w, r, err) return } httpapi.WriteResponse(w, r, output) }
Output:
Index ¶
- func ReadRequest(r *http.Request, body interface{}) error
- func WriteError(w http.ResponseWriter, r *http.Request, err error)
- func WriteResponse(w http.ResponseWriter, r *http.Request, body interface{})
- type HandlerFunc
- type Middleware
- type Stack
- type Values
- func (v *Values) Err() error
- func (v *Values) GetBool(name string) bool
- func (v *Values) GetDate(name string) local.Date
- func (v *Values) GetInt(name string) int
- func (v *Values) GetString(name string) string
- func (v *Values) GetTime(name string) time.Time
- func (v *Values) LookupBool(name string) (b bool, ok bool)
- func (v *Values) LookupDate(name string) (d local.Date, ok bool)
- func (v *Values) LookupInt(name string) (n int, ok bool)
- func (v *Values) LookupString(name string) (s string, ok bool)
- func (v *Values) LookupTime(name string) (t time.Time, ok bool)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ReadRequest ¶
ReadRequest reads the request body as JSON, and unmarshals it into the structure pointed to by body.
Although not specified in the HTTP spec, if the request contains a header "Content-Encoding: gzip", then the request body will be decompressed. This is convenient for HTTP clients that PUT or POST large JSON content.
func WriteError ¶
func WriteError(w http.ResponseWriter, r *http.Request, err error)
WriteError writes an error message as a JSON object.
The HTTP status code is retrieved from the error using the errkind package. If no status is associated with the error then a 500 status is returned.
Care is taken to ensure that no implementation details are leaked to the client. If the error implements the `publicer` interface (as defined in the errkind package), then the error's message and HTTP status are considered suitable for returning to the client. Otherwise a more general error message is returned.
If the client is considered a "trusted" client, then full details of the error are returned in an extra details key that is not present for untrusted clients. By default a client is trusted if the request originated on the local host (but does not include requests routed through a local reverse proxy).
The writeerror subdirectory package provides configuration on how errors are marshalled to the client, and how details of the errors are logged and/or traced. The defaults are sensible, so this function can be used with no configuration.
func WriteResponse ¶
func WriteResponse(w http.ResponseWriter, r *http.Request, body interface{})
WriteResponse sends the response as JSON to the HTTP client. The response is compressed if the HTTP client is able to accept compressed responses.
Types ¶
type HandlerFunc ¶
type HandlerFunc func(http.ResponseWriter, *http.Request) error
HandlerFunc is similar to http.HandlerFunc, but it returns an error.
func (HandlerFunc) ServeHTTP ¶
func (fn HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements the http.Handler interface.
type Middleware ¶
Middleware is a function that filters a request coming into the application and responses going back to the client. Middleware is similar in concept to Rack middleware.
type Stack ¶
type Stack struct {
// contains filtered or unexported fields
}
A Stack is a stack of middleware functions that are common to one or more HTTP handlers. A middleware function is any function that accepts a Handler as a parameter and returns a Handler.
func (*Stack) Handler ¶
Handler creates a http.Handler from a stack of middleware functions and a httpctx.Handler.
func (*Stack) HandlerFunc ¶
HandlerFunc returns a http.Handler (compatible with the standard library http package), which calls the middleware handlers in the stack s, followed by the handler function f.
func (*Stack) Use ¶
func (s *Stack) Use(f ...Middleware) *Stack
Use creates a new stack by appending the middleware functions to the existing stack.
type Values ¶
type Values struct {
// contains filtered or unexported fields
}
Values provides convenient methods for extracting arguments from the query string.
func (*Values) Err ¶
Err returns nil if no errors have been encountered, otherwise it returns a bad request error that lists the parameter(s) that are not in the correct format.
func (*Values) GetBool ¶
GetBool returns a bool. Returns false if the query value is not present in the query.
func (*Values) GetDate ¶
GetDate returns a date. The date should be in ISO8601 format. Returns zero if the date value if not present in the query.
func (*Values) GetInt ¶
GetInt returns an int. Returns 0 if the query value is not present in the query.
func (*Values) GetString ¶
GetString returns a string. Returns "" if the query value is not present in the query.
func (*Values) GetTime ¶
GetTime returns a time. The time should be in RFC3339 format. Returns zero if the time value if not present in the query.
func (*Values) LookupBool ¶
LookupBool returns a bool, with an indication of whether the query value was present in the query.
func (*Values) LookupDate ¶
LookupDate returns a date. The date should be in ISO8601 format.
func (*Values) LookupInt ¶
LookupInt returns an integer, with an indication of whether the query value was present.
func (*Values) LookupString ¶
LookupString returns a string, with an indication of whether the query value was present in the query.
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Package writeerror is used to configure how errors are marshalled and logged in calls to httpapi.WriteError.
|
Package writeerror is used to configure how errors are marshalled and logged in calls to httpapi.WriteError. |