From f7094ad78f6638d0e940a724fe5a857cc857155f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= <essen@ninenines.eu>
Date: Wed, 28 Dec 2016 15:16:10 +0100
Subject: Update the cowboy_rest manual

---
 doc/src/manual/cowboy_rest.asciidoc | 757 +++++++++++++++++++++---------------
 1 file changed, 448 insertions(+), 309 deletions(-)

(limited to 'doc/src/manual/cowboy_rest.asciidoc')

diff --git a/doc/src/manual/cowboy_rest.asciidoc b/doc/src/manual/cowboy_rest.asciidoc
index edf4b5c..26515fb 100644
--- a/doc/src/manual/cowboy_rest.asciidoc
+++ b/doc/src/manual/cowboy_rest.asciidoc
@@ -6,287 +6,363 @@ 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
+
+REST handlers implement the following interface:
+
+[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}
+
+Callback(Req, State)
+    -> {Result, Req, State}
+     | {stop, Req, State}
 
-== Meta values
+terminate(Reason, Req, State) -> ok  %% optional
 
-charset = binary()::
-	Negotiated charset.
-	+
-	This value may not be defined if no charset was negotiated.
+Req    :: cowboy_req:req()
+State  :: any()
+Reason :: normal
+        | {crash, error | exit | throw, any()}
 
-language = binary()::
-	Negotiated language.
-	+
-	This value may not be defined if no language was negotiated.
+Callback - see below
+Result   - see below
+Default  - see below
+----
 
-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`.
+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.
 
-== Terminate reasons
+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 following values may be received as the terminate reason
-in the optional `terminate/3` callback.
+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
-	used to obtain more information about the crash. The function
-	`erlang:get_stacktrace/0` can also be called to obtain the
-	stacktrace of the process when the crash occurred.
+    A crash occurred in the handler. `Class` and `Reason` can be
+    used to obtain more information about the crash. The function
+    `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
+----
+
+Process the request body.
+
+This function should create or update the resource using the
+request body.
 
-== REST callbacks description
+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}
 
-Return the list of allowed methods.
+Result  :: [binary()]  %% case sensitive
+Default :: [<<"GET">>, <<"HEAD">>, <<"OPTIONS">>]
+----
 
-Methods are case sensitive. Standard methods are always uppercase.
+Return the list of allowed methods.
 
 === 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.
+// @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.
 
-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.
+=== content_types_provided
 
-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`.
+[source,erlang]
+----
+content_types_provided(Req, State) -> {Result, Req, State}
 
-=== content_types_provided
+Result     :: [{binary() | ParsedMime, ProvideCallback :: atom()}]
+ParsedMime :: {Type :: binary(), SubType :: binary(), '*' | Params}
+Params     :: [{Key :: binary(), Value :: binary()}]
 
-Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
-Value type:: [{binary() | {Type, SubType, Params}, ProvideResource}]
+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}
 
-Return the entity tag of the resource.
+Result  :: binary() | {weak | strong, binary()}
+Default  - no etag value
+----
 
-This value will be sent as the value of the etag header.
+Return the entity tag of the resource.
 
-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}
+
+Result  :: boolean()
+Default :: false
+----
 
-Return whether the put action results in a conflict.
+Return whether the PUT request results in a conflict.
 
-A `409 Conflict` response will be sent if this function
-returns `true`.
+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}
+
+Result  :: [binary()]  %% lowercase; case insensitive
+Default  - skip this step
+----
 
-Return the list of languages the resource provides.
+Return the list of languages the resource provides in order
+of preference.
 
-The list must be ordered in order of preference.
+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.
 
-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.
+// @todo We should explain precisely how languages are picked.
 
-The chosen language will be set in the `Req` object as the meta
-value `language`.
+Cowboy will add the negotiated `language` to the Req object
+after this step completes:
 
-While languages are case insensitive, this callback is expected
-to return them as lowercase binary.
+[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}
 
-Return whether the request is malformed.
+Result  :: boolean()
+Default :: false
+----
 
-Cowboy has already performed all the necessary checks
-by the time this function is called, so few resources
-are expected to implement it.
+Return whether the request is malformed.
 
-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
-
-With types:
+[source,erlang]
+----
+moved_permanently(Req, State) -> {Result, Req, State}
 
-* URL = iodata()
+Result  :: {true, URI :: iodata()} | false
+Default :: false
+----
 
-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, and
+what its new location is.
 
-Return whether the resource was temporarily moved.
+=== multiple_choices
 
-If it was, its new URL is also returned and sent in the
-location header in the response.
+[source,erlang]
+----
+multiple_choices(Req, State) -> {Result, Req, State}
 
-=== multiple_choices
+Result  :: boolean()
+Default :: false
+----
 
-Methods:: GET, HEAD, POST, PUT, PATCH, DELETE
-Value type:: boolean()
-Default value:: false
+Return whether the client should engage in reactive
+negotiation.
 
-Return whether there are multiple representations of the resource.
+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.
 
-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)`.
+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}
 
-Return whether the resource exists.
+Result  :: boolean()
+Default :: true
+----
 
-If it exists, conditional headers will be tested before
-attempting to perform the action. Otherwise, Cowboy will
-check if the resource previously existed first.
+Return whether the resource exists.
 
 === service_available
 
-Methods:: all
-Value type:: boolean()
-Default value:: true
+[source,erlang]
+----
+service_available(Req, State) -> {Result, Req, State}
 
-Return whether the service is available.
+Result  :: boolean()
+Default :: true
+----
 
-This function can be used to test that all relevant backend
-systems are up and able to handle requests.
+Return whether the service is available.
 
-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}
 
-Return whether the requested URI is too long.
+Result  :: boolean()
+Default :: false
+----
 
-Cowboy has already performed all the necessary checks
-by the time this function is called, so few resources
-are expected to implement it.
+Return whether the requested URI is too long.
 
-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}
+
+Result  :: [binary()]  %% case insensitive
+Default :: []
+----
 
-Return the list of headers that affect the representation of the resource.
+Return the list of request headers that affect the
+representation of the resource.
 
-These request headers return the same resource but with different
-parameters, like another language or a different content-type.
+Cowboy automatically adds the accept, accept-charset and
+accept-language headers when necessary.
 
-Cowboy will automatically add the accept, accept-language and
-accept-charset headers to the list if the respective functions
-were defined in the resource.
+== See also
 
-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.
+link:man:cowboy(7)[cowboy(7)],
+link:man:cowboy_handler(3)[cowboy_handler(3)]
-- 
cgit v1.2.3

