mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 12:20:24 +00:00
Update the cowboy_rest manual
This commit is contained in:
parent
afc7d08813
commit
f7094ad78f
3 changed files with 465 additions and 325 deletions
|
@ -164,11 +164,10 @@ implement the `moved_permanently` callback.
|
|||
|
||||
=== The request
|
||||
|
||||
Do we need to perform extra checks to make sure the request
|
||||
is valid? Cowboy will do many checks when receiving the
|
||||
request already, do we need more? Note that this only
|
||||
applies to the request-line and headers of the request,
|
||||
and not the body. Implement `malformed_request`.
|
||||
Do you need to read the query string? Individual headers?
|
||||
Implement `malformed_request` and do all the parsing and
|
||||
validation in this function. Note that the body should not
|
||||
be read at this point.
|
||||
|
||||
May there be a request body? Will I know its size?
|
||||
What's the maximum size of the request body I'm willing
|
||||
|
|
|
@ -6,44 +6,65 @@ cowboy_rest - REST handlers
|
|||
|
||||
== Description
|
||||
|
||||
The `cowboy_rest` module implements REST semantics on top of
|
||||
the HTTP protocol.
|
||||
The module `cowboy_rest` implements the HTTP state machine.
|
||||
|
||||
This module is a sub protocol that defines many callbacks
|
||||
be implemented by handlers. The `init/2` and `terminate/3`
|
||||
callbacks are common to all handler types and are documented
|
||||
in the manual for the link:cowboy_handler.asciidoc[cowboy_handler] module.
|
||||
Implementing REST handlers is not enough to provide a REST
|
||||
interface; this interface must also follow the REST
|
||||
constraints including HATEOAS (hypermedia as the engine
|
||||
of application state).
|
||||
|
||||
All other callbacks are optional, though some may become
|
||||
required depending on the return value of previous callbacks.
|
||||
== Callbacks
|
||||
|
||||
== Meta values
|
||||
REST handlers implement the following interface:
|
||||
|
||||
charset = binary()::
|
||||
Negotiated charset.
|
||||
+
|
||||
This value may not be defined if no charset was negotiated.
|
||||
[source,erlang]
|
||||
----
|
||||
init(Req, State)
|
||||
-> {cowboy_rest, Req, State}
|
||||
| {cowboy_rest, Req, State, hibernate}
|
||||
| {cowboy_rest, Req, State, timeout()}
|
||||
| {cowboy_rest, Req, State, timeout(), hibernate}
|
||||
|
||||
language = binary()::
|
||||
Negotiated language.
|
||||
+
|
||||
This value may not be defined if no language was negotiated.
|
||||
Callback(Req, State)
|
||||
-> {Result, Req, State}
|
||||
| {stop, Req, State}
|
||||
|
||||
media_type = {binary(), binary(), '*' | [{binary(), binary()}]}::
|
||||
Negotiated media-type.
|
||||
+
|
||||
The media-type is the content-type, excluding the charset.
|
||||
+
|
||||
This value is always defined after the call to
|
||||
`content_types_provided/2`.
|
||||
terminate(Reason, Req, State) -> ok %% optional
|
||||
|
||||
== Terminate reasons
|
||||
Req :: cowboy_req:req()
|
||||
State :: any()
|
||||
Reason :: normal
|
||||
| {crash, error | exit | throw, any()}
|
||||
|
||||
The following values may be received as the terminate reason
|
||||
in the optional `terminate/3` callback.
|
||||
Callback - see below
|
||||
Result - see below
|
||||
Default - see below
|
||||
----
|
||||
|
||||
The `init/2` callback is common to all handlers. To switch
|
||||
to the REST handler behavior, it must return `cowboy_rest`
|
||||
as the first element of the tuple.
|
||||
|
||||
The `Callback/2` above represents all the REST-specific
|
||||
callbacks. They are described in the following section
|
||||
of this manual. REST-specific callbacks differ by their
|
||||
name, semantics, result and default values. The default
|
||||
value is the one used when the callback has not been
|
||||
implemented. They otherwise all follow the same interface.
|
||||
|
||||
The `stop` tuple can be returned to stop REST processing.
|
||||
If no response was sent before then, Cowboy will send a
|
||||
'204 No Content'.
|
||||
|
||||
The optional `terminate/3` callback will ultimately be called
|
||||
with the reason for the termination of the handler.
|
||||
Cowboy will terminate the process right after this. There
|
||||
is no need to perform any cleanup in this callback.
|
||||
|
||||
The following terminate reasons are defined for loop handlers:
|
||||
|
||||
normal::
|
||||
The connection was closed normally.
|
||||
The handler terminated normally.
|
||||
|
||||
{crash, Class, Reason}::
|
||||
A crash occurred in the handler. `Class` and `Reason` can be
|
||||
|
@ -51,242 +72,297 @@ normal::
|
|||
`erlang:get_stacktrace/0` can also be called to obtain the
|
||||
stacktrace of the process when the crash occurred.
|
||||
|
||||
== Callbacks
|
||||
== REST callbacks
|
||||
|
||||
=== Callback(Req, State) -> {Value, Req, State} | {stop, Req, State}
|
||||
=== AcceptCallback
|
||||
|
||||
Callback:: One of the REST callbacks described below.
|
||||
Req = cowboy_req:req():: The Req object.
|
||||
State = any():: Handler state.
|
||||
Value:: See the REST callbacks description below.
|
||||
// @todo The flowcharts should rename AcceptResource into AcceptCallback.
|
||||
|
||||
Please see the REST callbacks description below for details
|
||||
on the `Value` type, the default value if the callback is
|
||||
not defined, and more general information on when the
|
||||
callback is called and what its intended use is.
|
||||
[source,erlang]
|
||||
----
|
||||
AcceptCallback(Req, State) -> {Result, Req, State}
|
||||
|
||||
The `stop` tuple can be returned to stop REST processing.
|
||||
It is up to the resource code to send a reply before that,
|
||||
otherwise a `204 No Content` will be sent.
|
||||
Result :: true | {true, URI :: iodata()} | false}
|
||||
Default - crash
|
||||
----
|
||||
|
||||
== REST callbacks description
|
||||
Process the request body.
|
||||
|
||||
This function should create or update the resource using the
|
||||
request body.
|
||||
|
||||
For PUT requests, the body is a representation of the resource
|
||||
that is being created or replaced.
|
||||
|
||||
For POST requests, the body is typically application-specific
|
||||
instructions on how to process the request, but it may also
|
||||
be a representation of the resource. When creating a new
|
||||
resource with POST at a different location, return `{true, URI}`
|
||||
with `URI` the new location.
|
||||
|
||||
For PATCH requests, the body is a series of instructions on
|
||||
how to update the resource. Patch files or JSON Patch are
|
||||
examples of such media types.
|
||||
|
||||
A response body may be sent. The appropriate media type, charset
|
||||
and language for the response can be retrieved from the Req
|
||||
object using the `media_type`, `charset` and `language` keys,
|
||||
respectively. The body can be set using
|
||||
link:man:cowboy_req:set_resp_body(3)[cowboy_req:set_resp_body(3)].
|
||||
|
||||
=== allowed_methods
|
||||
|
||||
Methods:: all
|
||||
Value type:: [binary()]
|
||||
Default value:: `[<<"GET">>, <<"HEAD">>, <<"OPTIONS">>]`
|
||||
[source,erlang]
|
||||
----
|
||||
allowed_methods(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: [binary()] %% case sensitive
|
||||
Default :: [<<"GET">>, <<"HEAD">>, <<"OPTIONS">>]
|
||||
----
|
||||
|
||||
Return the list of allowed methods.
|
||||
|
||||
Methods are case sensitive. Standard methods are always uppercase.
|
||||
|
||||
=== allow_missing_post
|
||||
|
||||
Methods:: POST
|
||||
Value type:: boolean()
|
||||
Default value:: true
|
||||
[source,erlang]
|
||||
----
|
||||
allow_missing_post(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: boolean()
|
||||
Default :: true
|
||||
----
|
||||
|
||||
Return whether POST is allowed when the resource doesn't exist.
|
||||
|
||||
Returning `true` here means that a new resource will be
|
||||
created. The URL to the created resource should also be
|
||||
returned from the `AcceptResource` callback.
|
||||
created. The URI for the newly created resource should be
|
||||
returned from the `AcceptCallback` function.
|
||||
|
||||
=== charsets_provided
|
||||
|
||||
Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
|
||||
Value type:: [binary()]
|
||||
Default behavior:: Skip to the next step if undefined.
|
||||
[source,erlang]
|
||||
----
|
||||
charsets_provided(Req, State) -> {Result, Req, State}
|
||||
|
||||
Return the list of charsets the resource provides.
|
||||
Result :: [binary()] %% lowercase; case insensitive
|
||||
Default - skip this step
|
||||
----
|
||||
|
||||
The list must be ordered in order of preference.
|
||||
Return the list of charsets the resource provides in order
|
||||
of preference.
|
||||
|
||||
If the accept-charset header was not sent, the first charset
|
||||
in the list will be selected. Otherwise Cowboy will select
|
||||
the most appropriate charset from the list.
|
||||
During content negotiation Cowboy will pick the most
|
||||
appropriate charset for the client. The client advertises
|
||||
charsets it prefers with the accept-charset header. When
|
||||
that header is missing, Cowboy picks the first charset
|
||||
from the resource.
|
||||
|
||||
The chosen charset will be set in the `Req` object as the meta
|
||||
value `charset`.
|
||||
// @todo We should explain precisely how charsets are picked.
|
||||
|
||||
While charsets are case insensitive, this callback is expected
|
||||
to return them as lowercase binary.
|
||||
Cowboy will add the negotiated `charset` to the Req object
|
||||
after this step completes:
|
||||
|
||||
[source,erlang]
|
||||
----
|
||||
req() :: #{
|
||||
charset => binary() %% lowercase; case insensitive
|
||||
}
|
||||
----
|
||||
|
||||
=== content_types_accepted
|
||||
|
||||
Methods:: POST, PUT, PATCH
|
||||
Value type:: [{binary() | {Type, SubType, Params}, AcceptResource}]
|
||||
Default behavior:: Crash if undefined.
|
||||
[source,erlang]
|
||||
----
|
||||
content_types_accepted(Req, State) -> {Result, Req, State}
|
||||
|
||||
With types:
|
||||
Result :: [{binary() | ParsedMime, AcceptCallback :: atom()}]
|
||||
ParsedMime :: {Type :: binary(), SubType :: binary(), '*' | Params}
|
||||
Params :: [{Key :: binary(), Value :: binary()}]
|
||||
|
||||
* Type = SubType = binary()
|
||||
* Params = '*' | [{binary(), binary()}]
|
||||
* AcceptResource = atom()
|
||||
Default - crash
|
||||
----
|
||||
|
||||
Return the list of content-types the resource accepts.
|
||||
// @todo Case sensitivity of parsed mime content?
|
||||
|
||||
The list must be ordered in order of preference.
|
||||
Return the list of media types the resource accepts in
|
||||
order of preference.
|
||||
|
||||
Each content-type can be given either as a binary string or as
|
||||
a tuple containing the type, subtype and parameters.
|
||||
A media type is made of different parts. The media type
|
||||
`text/html;charset=utf-8` is of type `text`, subtype `html`
|
||||
and has a single parameter `charset` with value `utf-8`.
|
||||
|
||||
Cowboy will select the most appropriate content-type from the list.
|
||||
If any parameter is acceptable, then the tuple form should be used
|
||||
with parameters set to `'*'`. If the parameters value is set to `[]`
|
||||
only content-type values with no parameters will be accepted. All
|
||||
parameter values are treated in a case sensitive manner except the
|
||||
`charset` parameter, if present, which is case insensitive.
|
||||
// @todo Cowboy needs to ignore the boundary parameter for
|
||||
// multipart, as we never want to match against it. Or allow
|
||||
// ignoring specific parameters at the very least.
|
||||
|
||||
This function will be called for POST, PUT and PATCH requests.
|
||||
It is entirely possible to define different callbacks for different
|
||||
methods if the handling of the request differs. Simply verify
|
||||
what the method is with `cowboy_req:method/1` and return a
|
||||
different list for each methods.
|
||||
Cowboy will match the content-type request header against
|
||||
the media types the server accepts and select the appropriate
|
||||
callback. When that header is missing, or when the server does not
|
||||
accept this media type, the request fails and an error response
|
||||
is returned. Cowboy will execute the callback immediately otherwise.
|
||||
|
||||
The `AcceptResource` value is the name of the callback that will
|
||||
be called if the content-type matches. It is defined as follows.
|
||||
// @todo We should explain precisely how media types are picked.
|
||||
|
||||
Value type:: true | {true, URL} | false
|
||||
Default behavior:: Crash if undefined.
|
||||
An empty parameters list `[]` means that no parameters will be
|
||||
accepted. When any parameter is acceptable, the tuple form
|
||||
should be used with parameters as the atom `'*'`.
|
||||
|
||||
Process the request body.
|
||||
Cowboy treats all parameters as case sensitive, except for the
|
||||
`charset` parameter, which is known to be case insensitive. You
|
||||
should therefore always provide the charset as a lowercase
|
||||
binary string.
|
||||
|
||||
This function should create or update the resource with the
|
||||
information contained in the request body. This information
|
||||
may be full or partial depending on the request method.
|
||||
|
||||
If the request body was processed successfully, `true` must
|
||||
be returned. If the request method is POST, `{true, URL}` may
|
||||
be returned instead, and Cowboy will redirect the client to
|
||||
the location of the newly created resource.
|
||||
|
||||
If a response body must be sent, the appropriate media-type, charset
|
||||
and language can be retrieved using the `cowboy_req:meta/{2,3}`
|
||||
functions. The respective keys are `media_type`, `charset`
|
||||
and `language`. The body can be set using `cowboy_req:set_resp_body/2`.
|
||||
// @todo Maybe this should be in the user guide instead.
|
||||
//This function will be called for POST, PUT and PATCH requests.
|
||||
//It is entirely possible to define different callbacks for different
|
||||
//methods if the handling of the request differs. Simply verify
|
||||
//what the method is with `cowboy_req:method/1` and return a
|
||||
//different list for each methods.
|
||||
|
||||
=== content_types_provided
|
||||
|
||||
Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
|
||||
Value type:: [{binary() | {Type, SubType, Params}, ProvideResource}]
|
||||
[source,erlang]
|
||||
----
|
||||
content_types_provided(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: [{binary() | ParsedMime, ProvideCallback :: atom()}]
|
||||
ParsedMime :: {Type :: binary(), SubType :: binary(), '*' | Params}
|
||||
Params :: [{Key :: binary(), Value :: binary()}]
|
||||
|
||||
Default - [{{ <<"text">>, <<"html">>, '*'}, to_html}]
|
||||
----
|
||||
|
||||
// @todo Case sensitivity of parsed mime content?
|
||||
// @todo Space required for the time being: https://github.com/spf13/hugo/issues/2398
|
||||
Default value:: `[{{ <<"text">>, <<"html">>, '*'}, to_html}]`
|
||||
|
||||
With types:
|
||||
Return the list of media types the resource provides in
|
||||
order of preference.
|
||||
|
||||
* Type = SubType = binary()
|
||||
* Params = '*' | [{binary(), binary()}]
|
||||
* ProvideResource = atom()
|
||||
A media type is made of different parts. The media type
|
||||
`text/html;charset=utf-8` is of type `text`, subtype `html`
|
||||
and has a single parameter `charset` with value `utf-8`.
|
||||
|
||||
Return the list of content-types the resource provides.
|
||||
// @todo Cowboy needs to ignore the boundary parameter for
|
||||
// multipart, as we never want to match against it. Or allow
|
||||
// ignoring specific parameters at the very least.
|
||||
|
||||
The list must be ordered in order of preference.
|
||||
During content negotiation Cowboy will pick the most appropriate
|
||||
media type for the client. The client advertises media types it
|
||||
prefers with the accept header. When that header is missing,
|
||||
the content negotiation fails and an error response is returned.
|
||||
|
||||
Each content-type can be given either as a binary string or as
|
||||
a tuple containing the type, subtype and parameters.
|
||||
The callback given for the selected media type will be called
|
||||
at the end of the execution of GET and HEAD requests when a
|
||||
representation must be sent to the client.
|
||||
|
||||
Cowboy will select the most appropriate content-type from the list.
|
||||
If any parameter is acceptable, then the tuple form should be used
|
||||
with parameters set to `'*'`. If the parameters value is set to `[]`
|
||||
only content-type values with no parameters will be accepted. All
|
||||
parameter values are treated in a case sensitive manner except the
|
||||
`charset` parameter, if present, which is case insensitive.
|
||||
// @todo We should explain precisely how media types are picked.
|
||||
|
||||
The `ProvideResource` value is the name of the callback that will
|
||||
be called if the content-type matches. It will only be called when
|
||||
a representation of the resource needs to be returned. It is defined
|
||||
as follow.
|
||||
An empty parameters list `[]` means that no parameters will be
|
||||
accepted. When any parameter is acceptable, the tuple form
|
||||
should be used with parameters as the atom `'*'`.
|
||||
|
||||
Methods:: GET, HEAD
|
||||
Value type:: iodata() | {stream, Fun} | {stream, Len, Fun} | {chunked, ChunkedFun}
|
||||
Default behavior:: Crash if undefined.
|
||||
Cowboy treats all parameters as case sensitive, except for the
|
||||
`charset` parameter, which is known to be case insensitive. You
|
||||
should therefore always provide the charset as a lowercase
|
||||
binary string.
|
||||
|
||||
Return the response body.
|
||||
Cowboy will add the negotiated `media_type` to the Req object
|
||||
after this step completes:
|
||||
|
||||
The response body may be provided directly or through a fun.
|
||||
If a fun tuple is returned, the appropriate `set_resp_body_fun`
|
||||
function will be called. Please refer to the documentation for
|
||||
these functions for more information about the types.
|
||||
[source,erlang]
|
||||
----
|
||||
req() :: #{
|
||||
media_type => ParsedMime
|
||||
}
|
||||
----
|
||||
|
||||
The call to this callback happens a good time after the call to
|
||||
`content_types_provided/2`, when it is time to start rendering
|
||||
the response body.
|
||||
// @todo Case sensitivity of parsed mime content?
|
||||
|
||||
=== delete_completed
|
||||
|
||||
Methods:: DELETE
|
||||
Value type:: boolean()
|
||||
Default value:: true
|
||||
[source,erlang]
|
||||
----
|
||||
delete_completed(Req, State) -> {Result, Req, State}
|
||||
|
||||
Return whether the delete action has been completed.
|
||||
Result :: boolean()
|
||||
Default :: true
|
||||
----
|
||||
|
||||
This function should return `false` if there is no guarantee
|
||||
that the resource gets deleted immediately from the system,
|
||||
including from any internal cache.
|
||||
Return whether the resource has been fully deleted from the
|
||||
system, including from any internal cache.
|
||||
|
||||
When this function returns `false`, a `202 Accepted`
|
||||
response will be sent instead of a `200 OK` or `204 No Content`.
|
||||
Returning `false` will result in a '202 Accepted' response
|
||||
being sent instead of a '200 OK' or '204 No Content'.
|
||||
|
||||
=== delete_resource
|
||||
|
||||
Methods:: DELETE
|
||||
Value type:: boolean()
|
||||
Default value:: false
|
||||
[source,erlang]
|
||||
----
|
||||
delete_resource(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: boolean()
|
||||
Default :: false
|
||||
----
|
||||
|
||||
Delete the resource.
|
||||
|
||||
The value returned indicates if the action was successful,
|
||||
regardless of whether the resource is immediately deleted
|
||||
from the system.
|
||||
Cowboy will send an error response when this function
|
||||
returns `false`.
|
||||
|
||||
=== expires
|
||||
|
||||
Methods:: GET, HEAD
|
||||
Value type:: calendar:datetime() | binary() | undefined
|
||||
Default value:: undefined
|
||||
[source,erlang]
|
||||
----
|
||||
expires(Req, State) -> {Result, Req, State}
|
||||
|
||||
Return the date of expiration of the resource.
|
||||
Result :: calendar:datetime() | binary() | undefined
|
||||
Default :: undefined
|
||||
----
|
||||
|
||||
This date will be sent as the value of the expires header.
|
||||
Return the resource's expiration date.
|
||||
|
||||
=== forbidden
|
||||
|
||||
Methods:: all
|
||||
Value type:: boolean()
|
||||
Default value:: false
|
||||
[source,erlang]
|
||||
----
|
||||
forbidden(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: boolean()
|
||||
Default :: false
|
||||
----
|
||||
|
||||
Return whether access to the resource is forbidden.
|
||||
|
||||
A `403 Forbidden` response will be sent if this
|
||||
A '403 Forbidden' response will be sent if this
|
||||
function returns `true`. This status code means that
|
||||
access is forbidden regardless of authentication,
|
||||
and that the request shouldn't be repeated.
|
||||
|
||||
=== generate_etag
|
||||
|
||||
Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
|
||||
Value type:: binary() | {weak | strong, binary()}
|
||||
Default value:: undefined
|
||||
[source,erlang]
|
||||
----
|
||||
generate_etag(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: binary() | {weak | strong, binary()}
|
||||
Default - no etag value
|
||||
----
|
||||
|
||||
Return the entity tag of the resource.
|
||||
|
||||
This value will be sent as the value of the etag header.
|
||||
|
||||
If a binary is returned, then the value will be parsed
|
||||
to the tuple form automatically. The value must be in
|
||||
the same format as the etag header, including quotes.
|
||||
When a binary is returned, the value is automatically
|
||||
parsed to a tuple. The binary must be in the same
|
||||
format as the etag header, including quotes.
|
||||
|
||||
=== is_authorized
|
||||
|
||||
Methods:: all
|
||||
Value type:: true | {false, AuthHeader}
|
||||
Default value:: true
|
||||
[source,erlang]
|
||||
----
|
||||
is_authorized(Req, State) -> {Result, Req, State}
|
||||
|
||||
With types:
|
||||
|
||||
* AuthHead = iodata()
|
||||
Result :: true | {false, AuthHeader :: iodata()}
|
||||
Default - true
|
||||
----
|
||||
|
||||
Return whether the user is authorized to perform the action.
|
||||
|
||||
|
@ -294,26 +370,34 @@ This function should be used to perform any necessary
|
|||
authentication of the user before attempting to perform
|
||||
any action on the resource.
|
||||
|
||||
If the authentication fails, the value returned will be sent
|
||||
as the value for the www-authenticate header in the
|
||||
`401 Unauthorized` response.
|
||||
When authentication fails, the `AuthHeader` value will
|
||||
be sent in the www-authenticate header for the
|
||||
'401 Unauthorized' response.
|
||||
|
||||
=== is_conflict
|
||||
|
||||
Methods:: PUT
|
||||
Value type:: boolean()
|
||||
Default value:: false
|
||||
[source,erlang]
|
||||
----
|
||||
is_conflict(Req, State) -> {Result, Req, State}
|
||||
|
||||
Return whether the put action results in a conflict.
|
||||
Result :: boolean()
|
||||
Default :: false
|
||||
----
|
||||
|
||||
A `409 Conflict` response will be sent if this function
|
||||
returns `true`.
|
||||
Return whether the PUT request results in a conflict.
|
||||
|
||||
A '409 Conflict' response is sent when `true`.
|
||||
|
||||
=== known_methods
|
||||
|
||||
Methods:: all
|
||||
Value type:: [binary()]
|
||||
Default value:: `[<<"GET">>, <<"HEAD">>, <<"POST">>, <<"PUT">>, <<"PATCH">>, <<"DELETE">>, <<"OPTIONS">>]`
|
||||
[source,erlang]
|
||||
----
|
||||
known_methods(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: [binary()] %% case sensitive
|
||||
Default :: [<<"GET">>, <<"HEAD">>, <<"POST">>, <<"PUT">>,
|
||||
<<"PATCH">>, <<"DELETE">>, <<"OPTIONS">>]
|
||||
----
|
||||
|
||||
Return the list of known methods.
|
||||
|
||||
|
@ -323,208 +407,263 @@ returned, regardless of their use in the resource.
|
|||
The default value lists the methods Cowboy knows and
|
||||
implement in `cowboy_rest`.
|
||||
|
||||
Methods are case sensitive. Standard methods are always uppercase.
|
||||
|
||||
=== languages_provided
|
||||
|
||||
Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
|
||||
Value type:: [binary()]
|
||||
Default behavior:: Skip to the next step if undefined.
|
||||
[source,erlang]
|
||||
----
|
||||
languages_provided(Req, State) -> {Result, Req, State}
|
||||
|
||||
Return the list of languages the resource provides.
|
||||
Result :: [binary()] %% lowercase; case insensitive
|
||||
Default - skip this step
|
||||
----
|
||||
|
||||
The list must be ordered in order of preference.
|
||||
Return the list of languages the resource provides in order
|
||||
of preference.
|
||||
|
||||
If the accept-language header was not sent, the first language
|
||||
in the list will be selected. Otherwise Cowboy will select
|
||||
the most appropriate language from the list.
|
||||
During content negotiation Cowboy will pick the most
|
||||
appropriate language for the client. The client advertises
|
||||
languages it prefers with the accept-language header. When
|
||||
that header is missing, Cowboy picks the first language
|
||||
from the resource.
|
||||
|
||||
The chosen language will be set in the `Req` object as the meta
|
||||
value `language`.
|
||||
// @todo We should explain precisely how languages are picked.
|
||||
|
||||
While languages are case insensitive, this callback is expected
|
||||
to return them as lowercase binary.
|
||||
Cowboy will add the negotiated `language` to the Req object
|
||||
after this step completes:
|
||||
|
||||
[source,erlang]
|
||||
----
|
||||
req() :: #{
|
||||
language => binary() %% lowercase; case insensitive
|
||||
}
|
||||
----
|
||||
|
||||
=== last_modified
|
||||
|
||||
Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
|
||||
Value type:: calendar:datetime()
|
||||
Default value:: undefined
|
||||
[source,erlang]
|
||||
----
|
||||
last_modified(Req, State) -> {Result, Req, State}
|
||||
|
||||
Return the date of last modification of the resource.
|
||||
Result :: calendar:datetime()
|
||||
Default - no last modified value
|
||||
----
|
||||
|
||||
Return the resource's last modification date.
|
||||
|
||||
This date will be used to test against the if-modified-since
|
||||
and if-unmodified-since headers, and sent as the last-modified
|
||||
header in the response of GET and HEAD requests.
|
||||
header in the response to GET and HEAD requests.
|
||||
|
||||
=== malformed_request
|
||||
|
||||
Methods:: all
|
||||
Value type:: boolean()
|
||||
Default value:: false
|
||||
[source,erlang]
|
||||
----
|
||||
malformed_request(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: boolean()
|
||||
Default :: false
|
||||
----
|
||||
|
||||
Return whether the request is malformed.
|
||||
|
||||
Cowboy has already performed all the necessary checks
|
||||
by the time this function is called, so few resources
|
||||
are expected to implement it.
|
||||
|
||||
The check is to be done on the request itself, not on
|
||||
the request body, which is processed later.
|
||||
A request is malformed when a component required by the
|
||||
resource is invalid. This may include the query string
|
||||
or individual headers. They should be parsed and validated
|
||||
in this function. The body should not be read at this point.
|
||||
|
||||
=== moved_permanently
|
||||
|
||||
Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
|
||||
Value type:: {true, URL} | false
|
||||
Default value:: false
|
||||
[source,erlang]
|
||||
----
|
||||
moved_permanently(Req, State) -> {Result, Req, State}
|
||||
|
||||
With types:
|
||||
Result :: {true, URI :: iodata()} | false
|
||||
Default :: false
|
||||
----
|
||||
|
||||
* URL = iodata()
|
||||
|
||||
Return whether the resource was permanently moved.
|
||||
|
||||
If it was, its new URL is also returned and sent in the
|
||||
location header in the response.
|
||||
Return whether the resource was permanently moved, and
|
||||
what its new location is.
|
||||
|
||||
=== moved_temporarily
|
||||
|
||||
Methods:: GET, HEAD, POST, PATCH, DELETE
|
||||
Value type:: {true, URL} | false
|
||||
Default value:: false
|
||||
[source,erlang]
|
||||
----
|
||||
moved_temporarily(Req, State) -> {Result, Req, State}
|
||||
|
||||
With types:
|
||||
Result :: {true, URI :: iodata()} | false
|
||||
Default :: false
|
||||
----
|
||||
|
||||
* URL = iodata()
|
||||
|
||||
Return whether the resource was temporarily moved.
|
||||
|
||||
If it was, its new URL is also returned and sent in the
|
||||
location header in the response.
|
||||
Return whether the resource was temporarily moved, and
|
||||
what its new location is.
|
||||
|
||||
=== multiple_choices
|
||||
|
||||
Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
|
||||
Value type:: boolean()
|
||||
Default value:: false
|
||||
[source,erlang]
|
||||
----
|
||||
multiple_choices(Req, State) -> {Result, Req, State}
|
||||
|
||||
Return whether there are multiple representations of the resource.
|
||||
Result :: boolean()
|
||||
Default :: false
|
||||
----
|
||||
|
||||
This function should be used to inform the client if there
|
||||
are different representations of the resource, for example
|
||||
different content-type. If this function returns `true`,
|
||||
the response body should include information about these
|
||||
different representations using `cowboy_req:set_resp_body/2`.
|
||||
The content-type of the response should be the one previously
|
||||
negociated and that can be obtained by calling
|
||||
`cowboy_req:meta(media_type, Req)`.
|
||||
Return whether the client should engage in reactive
|
||||
negotiation.
|
||||
|
||||
Return `true` when the server has multiple representations
|
||||
of a resource, each with their specific identifier, but is
|
||||
unable to determine which is best for the client. For
|
||||
example an image might have different sizes and the server
|
||||
is unable to determine the capabilities of the client.
|
||||
|
||||
When returning `true` the server should send a body with
|
||||
links to the different representations. If the server has
|
||||
a preferred representation it can send its link inside a
|
||||
location header.
|
||||
|
||||
=== options
|
||||
|
||||
Methods:: OPTIONS
|
||||
Value type:: ok
|
||||
Default value:: ok
|
||||
[source,erlang]
|
||||
----
|
||||
options(Req, State) -> {ok, Req, State}
|
||||
----
|
||||
|
||||
Handle a request for information.
|
||||
Respond to an OPTIONS request.
|
||||
|
||||
The response should inform the client the communication
|
||||
options available for this resource.
|
||||
|
||||
By default, Cowboy will send a `200 OK` response with the
|
||||
allow header set.
|
||||
options available for this resource. By default Cowboy
|
||||
will send a '200 OK' response with the allow header set.
|
||||
|
||||
=== previously_existed
|
||||
|
||||
Methods:: GET, HEAD, POST, PATCH, DELETE
|
||||
Value type:: boolean()
|
||||
Default value:: false
|
||||
[source,erlang]
|
||||
----
|
||||
previously_existed(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: boolean()
|
||||
Default :: false
|
||||
----
|
||||
|
||||
Return whether the resource existed previously.
|
||||
|
||||
=== ProvideCallback
|
||||
|
||||
[source,erlang]
|
||||
----
|
||||
ProvideCallback(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: cowboy_req:resp_body()
|
||||
Default - crash
|
||||
----
|
||||
|
||||
Return the response body.
|
||||
|
||||
The response body can be provided either as the actual data
|
||||
to be sent or a tuple indicating which file to send.
|
||||
|
||||
This function is called for both GET and HEAD requests. For
|
||||
the latter the body is not sent, however.
|
||||
|
||||
// @todo Perhaps we can optimize HEAD requests and just
|
||||
// allow calculating the length instead of returning the
|
||||
// whole thing.
|
||||
|
||||
Note that there used to be a way to stream the response body.
|
||||
It was temporarily removed and will be added back in a later
|
||||
release.
|
||||
|
||||
// @todo Add a way to switch to loop handler for streaming the body.
|
||||
|
||||
=== resource_exists
|
||||
|
||||
Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
|
||||
Value type:: boolean()
|
||||
Default value:: true
|
||||
[source,erlang]
|
||||
----
|
||||
resource_exists(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: boolean()
|
||||
Default :: true
|
||||
----
|
||||
|
||||
Return whether the resource exists.
|
||||
|
||||
If it exists, conditional headers will be tested before
|
||||
attempting to perform the action. Otherwise, Cowboy will
|
||||
check if the resource previously existed first.
|
||||
|
||||
=== service_available
|
||||
|
||||
Methods:: all
|
||||
Value type:: boolean()
|
||||
Default value:: true
|
||||
[source,erlang]
|
||||
----
|
||||
service_available(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: boolean()
|
||||
Default :: true
|
||||
----
|
||||
|
||||
Return whether the service is available.
|
||||
|
||||
This function can be used to test that all relevant backend
|
||||
systems are up and able to handle requests.
|
||||
|
||||
A `503 Service Unavailable` response will be sent if this
|
||||
A '503 Service Unavailable' response will be sent when this
|
||||
function returns `false`.
|
||||
|
||||
=== uri_too_long
|
||||
|
||||
Methods:: all
|
||||
Value type:: boolean()
|
||||
Default value:: false
|
||||
[source,erlang]
|
||||
----
|
||||
uri_too_long(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: boolean()
|
||||
Default :: false
|
||||
----
|
||||
|
||||
Return whether the requested URI is too long.
|
||||
|
||||
Cowboy has already performed all the necessary checks
|
||||
by the time this function is called, so few resources
|
||||
are expected to implement it.
|
||||
|
||||
A `414 Request-URI Too Long` response will be sent if this
|
||||
function returns `true`.
|
||||
This function can be used to further restrict the length
|
||||
of the URI for this specific resource.
|
||||
|
||||
=== valid_content_headers
|
||||
|
||||
Methods:: all
|
||||
Value type:: boolean()
|
||||
Default value:: true
|
||||
[source,erlang]
|
||||
----
|
||||
valid_content_headers(Req, State) -> {Result, Req, State}
|
||||
|
||||
Return whether the content-* headers are valid.
|
||||
Result :: boolean()
|
||||
Default :: true
|
||||
----
|
||||
|
||||
This also applies to the transfer-encoding header. This
|
||||
function must return `false` for any unknown content-*
|
||||
headers, or if the headers can't be understood. The
|
||||
function `cowboy_req:parse_header/2` can be used to
|
||||
quickly check the headers can be parsed.
|
||||
Return whether the content headers are valid.
|
||||
|
||||
A `501 Not Implemented` response will be sent if this
|
||||
function returns `false`.
|
||||
This callback can be used to reject requests that have
|
||||
invalid content header values, for example an unsupported
|
||||
content-encoding.
|
||||
|
||||
=== valid_entity_length
|
||||
|
||||
Methods:: all
|
||||
Value type:: boolean()
|
||||
Default value:: true
|
||||
[source,erlang]
|
||||
----
|
||||
valid_entity_length(Req, State) -> {Result, Req, State}
|
||||
|
||||
Result :: boolean()
|
||||
Default :: true
|
||||
----
|
||||
|
||||
Return whether the request body length is within acceptable boundaries.
|
||||
|
||||
A `413 Request Entity Too Large` response will be sent if this
|
||||
A '413 Request Entity Too Large' response will be sent if this
|
||||
function returns `false`.
|
||||
|
||||
=== variances
|
||||
|
||||
Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
|
||||
Value type:: [binary()]
|
||||
Default value:: []
|
||||
[source,erlang]
|
||||
----
|
||||
variances(Req, State) -> {Result, Req, State}
|
||||
|
||||
Return the list of headers that affect the representation of the resource.
|
||||
Result :: [binary()] %% case insensitive
|
||||
Default :: []
|
||||
----
|
||||
|
||||
These request headers return the same resource but with different
|
||||
parameters, like another language or a different content-type.
|
||||
Return the list of request headers that affect the
|
||||
representation of the resource.
|
||||
|
||||
Cowboy will automatically add the accept, accept-language and
|
||||
accept-charset headers to the list if the respective functions
|
||||
were defined in the resource.
|
||||
Cowboy automatically adds the accept, accept-charset and
|
||||
accept-language headers when necessary.
|
||||
|
||||
This operation is performed right before the `resource_exists/2`
|
||||
callback. All responses past that point will contain the vary
|
||||
header which holds this list.
|
||||
== See also
|
||||
|
||||
link:man:cowboy(7)[cowboy(7)],
|
||||
link:man:cowboy_handler(3)[cowboy_handler(3)]
|
||||
|
|
|
@ -100,6 +100,8 @@ ParsedMime :: {Type :: binary(), SubType :: binary(), Params}
|
|||
Params :: [{Key :: binary(), Value :: binary()}]
|
||||
----
|
||||
|
||||
// @todo Case sensitivity of parsed mime content?
|
||||
|
||||
Cowboy comes with two such functions; the default function
|
||||
`cow_mimetypes:web/1`, and a second function generated from
|
||||
the Apache 'mime.types' file, `cow_mimetypes:all/1`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue