0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-16 13:10:24 +00:00

Improve handler interface and documentation

This change simplifies a little more the sub protocols mechanism.
Aliases have been removed. The renaming of loop handlers as long
polling handlers has been reverted.

Plain HTTP handlers now simply do their work in the init/2
callback. There is no specific code for them.

Loop handlers now follow the same return value as Websocket,
they use ok to continue and shutdown to stop.

Terminate reasons for all handler types have been documented.
The terminate callback is now appropriately called in all cases
(or should be).

Behaviors for all handler types have been moved in the module
that implement them. This means that cowboy_handler replaces
the cowboy_http_handler behavior, and similarly cowboy_loop
replaces cowboy_loop_handler, cowboy_websocket replaces
cowboy_websocket_handler. Finally cowboy_rest now has the
start of a behavior in it and will have the full list of
optional callbacks defined once Erlang 18.0 gets released.

The guide has been reorganized and should be easier to follow.
This commit is contained in:
Loïc Hoguin 2014-09-30 20:12:13 +03:00
parent 5ce4c2bfb4
commit 0dc063ab7d
82 changed files with 778 additions and 1037 deletions

View file

@ -0,0 +1,99 @@
::: Handlers
Handlers are Erlang modules that handle HTTP requests.
:: Plain HTTP handlers
The most basic handler in Cowboy implements the mandatory
`init/2` callback, manipulates the request, optionally
sends a response and then returns.
This callback receives the ^"Req object^req and the options
defined during the ^"router configuration^routing^.
A handler that does nothing would look like this:
``` erlang
init(Req, Opts) ->
{ok, Req, Opts}.
```
Despite sending no reply, a `204 No Content` reply will be
sent to the client, as Cowboy makes sure that a reply is
sent for every request.
We need to use the Req object for sending a reply.
``` erlang
init(Req, Opts) ->
Req2 = cowboy_req:reply(200, [
{<<"content-type">>, <<"text/plain">>}
], <<"Hello World!">>, Req),
{ok, Req2, Opts}.
```
As you can see we return a 3-tuple. `ok` means that the
handler ran successfully. The Req object is returned as
it may have been modified as is the case here: replying
returns a modified Req object that you need to return
back to Cowboy for proper operations.
The last value of the tuple is a state that will be used
in every subsequent callbacks to this handler. Plain HTTP
handlers only have one additional callback, the optional
`terminate/3`.
:: Other handlers
The `init/2` callback can also be used to inform Cowboy
that this is a different kind of handler and that Cowboy
should switch to it. To do this you simply need to return
the module name of the handler type you want to switch to.
Cowboy comes with three handler types you can switch to:
^"cowboy_rest^rest_handlers^, ^"cowboy_websocket^ws_handlers^
and ^"cowboy_loop^loop_handlers^. In addition to those you
can define your own handler types.
Switching is simple. Instead of returning `ok`, you simply
return the name of the handler type you want to use. The
following snippet switches to a Websocket handler:
``` erlang
init(Req, Opts) ->
{cowboy_websocket, Req, Opts}.
```
You can also switch to your own custom handler type:
``` erlang
init(Req, Opts) ->
{my_handler_type, Req, Opts}.
```
How to implement a custom handler type is described in the
^"Sub protocols^sub_protocols chapter.
:: Cleaning up
All handlers coming with Cowboy allow the use of the optional
`terminate/3` callback.
``` erlang
terminate(_Reason, Req, State) ->
ok.
```
This callback is strictly reserved for any required cleanup.
You cannot send a response from this function. There is no
other return value.
If you used the process dictionary, timers, monitors or may
be receiving messages, then you can use this function to clean
them up, as Cowboy might reuse the process for the next
keep-alive request.
Note that while this function may be called in a Websocket
handler, it is generally not useful to do any clean up as
the process terminates immediately after calling this callback
when using Websocket.