From 06e74355c0a993b416b21bb4e9586c37973e8d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Tue, 1 Jan 2013 18:27:41 +0100 Subject: Add a skeleton of the guide to ease user contributions Has some stuff that aren't in master yet, and lacks a lot more that is already in master. --- guide/handlers.md | 39 ++++++++++++ guide/hooks.md | 12 ++++ guide/http_handlers.md | 17 ++++++ guide/internals.md | 13 ++++ guide/loop_handlers.md | 23 +++++++ guide/req.md | 22 +++++++ guide/rest_handlers.md | 28 +++++++++ guide/routing.md | 154 +++++++++++++++++++++++++++++++++++++++++++++++ guide/static_handlers.md | 14 +++++ guide/toc.md | 20 +++--- guide/ws_handlers.md | 21 +++++++ 11 files changed, 353 insertions(+), 10 deletions(-) create mode 100644 guide/handlers.md create mode 100644 guide/hooks.md create mode 100644 guide/http_handlers.md create mode 100644 guide/internals.md create mode 100644 guide/loop_handlers.md create mode 100644 guide/req.md create mode 100644 guide/rest_handlers.md create mode 100644 guide/routing.md create mode 100644 guide/static_handlers.md create mode 100644 guide/ws_handlers.md diff --git a/guide/handlers.md b/guide/handlers.md new file mode 100644 index 0000000..dac5460 --- /dev/null +++ b/guide/handlers.md @@ -0,0 +1,39 @@ +Handlers +======== + +Purpose +------- + +Handlers are Erlang modules that represent a resource. + +Handlers must process the request and send a reply. The nature of the +reply will vary between handlers. + +Different kinds of handlers can be combined in a single module. This +allows a module to handle both websocket and long-polling code in a +single place, for example. + +Protocol upgrades +----------------- + +Cowboy features many different handlers: HTTP handlers, loop handlers, +websocket handlers, REST handlers and static handlers. All of them +have a common entry point: the `init/3` function. + +By default, Cowboy considers your handler to be an HTTP handler. + +To switch to a different protocol, like, for example, Websocket, +you must perform a protocol upgrade. This is done by returning +a protocol upgrade tuple at the end of `init/3`. + +The following snippet upgrades the handler to `my_protocol`. + +``` erlang +init(_Any, _Req, _Opts) -> + {upgrade, protocol, my_protocol}. +``` + +The `my_protocol` module will be used for further processing of the +request. It requires only one callback, `upgrade/4`. + +@todo Describe `upgrade/4` when the middleware code gets pushed. diff --git a/guide/hooks.md b/guide/hooks.md new file mode 100644 index 0000000..ba48c4a --- /dev/null +++ b/guide/hooks.md @@ -0,0 +1,12 @@ +Hooks +===== + +On request +---------- + +@todo Describe. + +On response +----------- + +@todo Describe. diff --git a/guide/http_handlers.md b/guide/http_handlers.md new file mode 100644 index 0000000..0d8886d --- /dev/null +++ b/guide/http_handlers.md @@ -0,0 +1,17 @@ +HTTP handlers +============= + +Purpose +------- + +HTTP handlers are the simplest Cowboy module to handle a request. + +Callbacks +--------- + +@todo Describe the callbacks. + +Usage +----- + +@todo Explain how to use them. diff --git a/guide/internals.md b/guide/internals.md new file mode 100644 index 0000000..431ca01 --- /dev/null +++ b/guide/internals.md @@ -0,0 +1,13 @@ +Internals +========= + +Architecture +------------ + +@todo Describe. + +Efficiency considerations +------------------------- + +@todo Mention that you need to cleanup in terminate especially if you +used the process dictionary, started timers, started monitoring... diff --git a/guide/loop_handlers.md b/guide/loop_handlers.md new file mode 100644 index 0000000..67f8ec9 --- /dev/null +++ b/guide/loop_handlers.md @@ -0,0 +1,23 @@ +Loop handlers +============= + +Purpose +------- + +Loop handlers are a special kind of HTTP handlers used when the +response can not be sent right away. The handler enters instead +a receive loop waiting for the right message before it can send +a response. + +They are most useful when performing long-polling operations or +when using server-sent events. + +Callbacks +--------- + +@todo Describe the callbacks. + +Usage +----- + +@todo Explain how to use them. diff --git a/guide/req.md b/guide/req.md new file mode 100644 index 0000000..79c59a9 --- /dev/null +++ b/guide/req.md @@ -0,0 +1,22 @@ +Request object +============== + +Purpose +------- + +@todo Describe. + +Request +------- + +@todo Describe. + +Request body +------------ + +@todo Describe. + +Reply +----- + +@todo Describe. diff --git a/guide/rest_handlers.md b/guide/rest_handlers.md new file mode 100644 index 0000000..df5f841 --- /dev/null +++ b/guide/rest_handlers.md @@ -0,0 +1,28 @@ +REST handlers +============= + +Purpose +------- + +REST is a set of constraints that, when applied to HTTP, dictates how +resources must behave. It is the recommended way to handle requests +with Cowboy. + +REST is implemented in Cowboy as a protocol upgrade. Once upgraded, +the request is handled as a state machine with many optional callbacks +describing the resource and modifying the machine's behavior. + +Flow diagram +------------ + +@todo Add the beautiful flow diagram here. + +Callbacks +--------- + +@todo Describe the callbacks. + +Usage +----- + +@todo Explain how to use them. diff --git a/guide/routing.md b/guide/routing.md new file mode 100644 index 0000000..936b37c --- /dev/null +++ b/guide/routing.md @@ -0,0 +1,154 @@ +Routing +======= + +@todo Note that this documentation is for the new routing interface +not available in master at this point. + +Purpose +------- + +Cowboy does nothing by default. + +To make Cowboy useful, you need to map URLs to Erlang modules that will +handle the requests. This is called routing. + +When Cowboy receives a request, it tries to match the requested host and +path to the resources given in the dispatch rules. If it matches, then +the associated Erlang code will be executed. + +Routing rules are given per host. Cowboy will first match on the host, +and then try to find a matching path. + +Routes need to be compiled before they can be used by Cowboy. + +Structure +--------- + +The general structure for the routes is defined as follow. + +``` erlang +Routes = [Host1, Host2, ... HostN]. +``` + +Each host contains matching rules for the host along with optional +constraints, and a list of routes for the path component. + +``` erlang +Host1 = {HostMatch, PathsList}. +Host2 = {HostMatch, Constraints, PathsList}. +``` + +The list of routes for the path component is defined similar to the +list of hosts. + +``` erlang +PathsList = [Path1, Path2, ... PathN]. +``` + +Finally, each path contains matching rules for the path along with +optional constraints, and gives us the handler module to be used +along with options that will be given to it on initialization. + +``` +Path1 = {PathMatch, Handler, Module}. +Path2 = {PathMatch, Constraints, Handler, Module}. +``` + +Continue reading to learn more about the match syntax and the optional +constraints. + +Match syntax +------------ + +The match syntax is used to associate host names and paths with their +respective handlers. + +The match syntax is the same for host and path with a few subtleties. +Indeed, the segments separator is different, and the host is matched +starting from the last segment going to the first. All examples will +feature both host and path match rules and explain the differences +when encountered. + +Excluding special values that we will explain at the end of this section, +the simplest match value is a host or a path. It can be given as either +a `string()` or a `binary()`. + +``` erlang +PathMatch1 = "/". +PathMatch2 = "/path/to/resource". + +HostMatch1 = "cowboy.example.org". +``` + +As you can see, all paths defined this way must start with a slash +character. Note that these two paths are identical as far as routing +is concerned. + +``` erlang +PathMatch2 = "/path/to/resource". +PathMatch3 = "/path/to/resource/". +``` + +Hosts with and without a trailing dot are equivalent for routing. + +``` erlang +HostMatch1 = "cowboy.example.org". +HostMatch2 = "cowboy.example.org.". +``` + +It is possible to extract segments of the host and path and to store +the values in the `Req` object for later use. We call these kind of +values bindings. + +The syntax for bindings is very simple. A segment that begins with +the `:` character means that what follows until the end of the segment +is the name of the binding in which the segment value will be stored. + +``` erlang +PathMatch = "/hats/:name/prices". +HostMatch = ":subdomain.example.org". +``` + +If these two end up matching when routing, you will end up with two +bindings defined, `subdomain` and `hat_name`, each containing the +segment value where they were defined. For example, the URL +`http://test.example.org/hats/wild_cowboy_legendary/prices` will +result in having the value `test` bound to the name `subdomain` +and the value `wild_cowboy_legendary` bound to the name `hat_name`. +They can later be retrieved using `cowboy_req:binding/{2,3}`. + +@todo special binding `'_'` +@todo optional path or segments +@todo same binding twice (+ optional + host/path) + +Constraints +----------- + +@todo Describe constraints. + +Compilation +----------- + +The structure defined in this chapter needs to be compiled before it is +passed to Cowboy. This allows Cowboy to efficiently lookup the correct +handler to run instead of having to parse the routes repeatedly. + +This can be done with a simple call to `cowboy_routing:compile/1`. + +@todo Note that the `routes` option will be specified slightly differently +when middleware support gets in. + +``` erlang +{ok, Routes} = cowboy_routing:compile([ + %% {URIHost, list({URIPath, Handler, Opts})} + {'_', [{'_', my_handler, []}]} +]), +%% Name, NbAcceptors, TransOpts, ProtoOpts +cowboy:start_http(my_http_listener, 100, + [{port, 8080}], + [{routes, Routes}] +). +``` + +Note that this function will return `{error, badarg}` if the structure +given is incorrect. diff --git a/guide/static_handlers.md b/guide/static_handlers.md new file mode 100644 index 0000000..5c897dd --- /dev/null +++ b/guide/static_handlers.md @@ -0,0 +1,14 @@ +Static handlers +=============== + +Purpose +------- + +Static handlers are a built-in REST handler for serving files. They +are available as a convenience and provide fast file serving with +proper cache handling. + +Usage +----- + +@todo Describe. diff --git a/guide/toc.md b/guide/toc.md index b57b92e..32234cd 100644 --- a/guide/toc.md +++ b/guide/toc.md @@ -6,43 +6,43 @@ Cowboy User Guide * Prerequisites * Conventions * Getting started - * Routing + * [Routing](routing.md) * Purpose * Dispatch list * Match rules * Bindings * Constraints - * Handlers + * [Handlers](handlers.md) * Purpose * Protocol upgrades - * HTTP handlers + * [HTTP handlers](http_handlers.md) * Purpose * Callbacks * Usage - * Loop handlers + * [Loop handlers](loop_handlers.md) * Purpose * Callbacks * Usage - * Websocket handlers + * [Websocket handlers](ws_handlers.md) * Purpose * Callbacks * Usage - * REST handlers + * [REST handlers](rest_handlers.md) * Purpose * Flow diagram * Callbacks * Usage - * Static handlers + * [Static handlers](static_handlers.md) * Purpose * Usage - * Request object + * [Request object](req.md) * Purpose * Request * Request body * Reply - * Hooks + * [Hooks](hooks.md) * On request * On response - * Internals + * [Internals](internals.md) * Architecture * Efficiency considerations diff --git a/guide/ws_handlers.md b/guide/ws_handlers.md new file mode 100644 index 0000000..fc5d953 --- /dev/null +++ b/guide/ws_handlers.md @@ -0,0 +1,21 @@ +Websocket handlers +================== + +Purpose +------- + +Websockets are an extension to HTTP to emulate plain TCP connections +between the user's browser and the server. Requests that are upgraded +are then handled by websocket handlers. + +Both sides of the socket can send data at any time asynchronously. + +Callbacks +--------- + +@todo Describe the callbacks. + +Usage +----- + +@todo Explain how to use them. -- cgit v1.2.3