diff options
authorLoïc Hoguin <[email protected]>2014-08-01 14:27:04 +0200
committerLoïc Hoguin <[email protected]>2014-08-01 14:27:04 +0200
commit8d436c4744437e4b56d833e561613d0c9cd0fcab (patch)
parent62de3a62f9981c3fe436cb50465d10b17ee9678b (diff)
Update the Getting started chapter to new erlang.mk
Length of the chapter divided by 2! \o/
1 files changed, 106 insertions, 243 deletions
diff --git a/doc/src/guide/getting_started.ezdoc b/doc/src/guide/getting_started.ezdoc
index ff34699..81fbc99 100644
--- a/doc/src/guide/getting_started.ezdoc
+++ b/doc/src/guide/getting_started.ezdoc
@@ -12,295 +12,158 @@ Cowboy, writing your first application and generating your first
release. At the end of this chapter you should know everything
you need to push your first Cowboy application to production.
-:: Application skeleton
+:: Bootstrap
-Let's start by creating this application. We will simply call it
-`hello_erlang`. This application will have the following directory
+We are going to use the ^"erlang.mk^https://github.com/extend/erlang.mk
+build system. It also offers bootstrap features allowing us to
+quickly get started without having to deal with minute details.
-``` bash
- src/
- hello_erlang.app.src
- hello_erlang_app.erl
- hello_erlang_sup.erl
- hello_handler.erl
- erlang.mk
- Makefile
- relx.config
-Once the release is generated, we will also have the following
-files added:
-``` bash
- ebin/
- hello_erlang.app
- hello_erlang_app.beam
- hello_erlang_sup.beam
- hello_handler.beam
- _rel/
- relx
-As you can probably guess, the `.app.src` file end up becoming
-the `.app` file, and the `.erl` files are compiled into `.beam`.
-Then, the whole release will be copied into the `_rel/` directory.
-The `.app` file contains various informations about the application.
-It contains its name, a description, a version, a list of modules,
-default configuration and more.
-Using a build system like ^"erlang.mk^https://github.com/extend/erlang.mk^,
-the list of modules will be included automatically in the `.app` file,
-so you don't need to manually put them in your `.app.src` file.
-For generating the release, we will use ^"relx^https://github.com/erlware/relx
-as it is a much simpler alternative to the tool coming with Erlang.
-First, create the `hello_erlang` directory. It should have the same name
-as the application within it. Then we create the `src` directory inside
-it, which will contain the source code for our application.
+First, let's create the directory for our application.
``` bash
$ mkdir hello_erlang
$ cd hello_erlang
-$ mkdir src
-Let's first create the `hello_erlang.app.src` file. It should be pretty
-straightforward for the most part. You can use the following template
-and change what you like in it.
+Then we need to download `erlang.mk`. Either use the following
+command or download it manually.
-``` erlang
-{application, hello_erlang, [
- {description, "Hello world with Cowboy!"},
- {vsn, "0.1.0"},
- {modules, []},
- {registered, [hello_erlang_sup]},
- {applications, [
- kernel,
- stdlib,
- cowboy
- ]},
- {mod, {hello_erlang_app, []}},
- {env, []}
+``` bash
+$ wget https://raw.githubusercontent.com/extend/erlang.mk/master/erlang.mk
-The `modules` line will be replaced with the list of modules during
-compilation. Make sure to leave this line even if you do not use it
-The `registered` value indicates which processes are registered by this
-application. You will often only register the top-level supervisor
-of the application.
-The `applications` value lists the applications that must be started
-for this application to work. The Erlang release will start all the
-applications listed here automatically.
+We can now bootstrap our application. Since we are going to generate
+a release, we will also bootstrap it at the same time.
-The `mod` value defines how the application should be started. Erlang
-will use the `hello_erlang_app` module for starting the application.
-The `hello_erlang_app` module is what we call an application behavior.
-The application behavior must define two functions: `start/2` and
-`stop/1`, for starting and stopping the application. A typical
-application module would look like this:
-``` erlang
+``` bash
+$ make -f erlang.mk bootstrap bootstrap-rel
-start(_Type, _Args) ->
- hello_erlang_sup:start_link().
+This creates a Makefile, a base application, and the release files
+necessary for creating the release. We can already build and start
+this release.
-stop(_State) ->
- ok.
+``` bash
+$ make
+$ ./_rel/hello_erlang_release/bin/hello_erlang_release console
-That's not enough however. Since we are building a Cowboy based
-application, we also need to initialize Cowboy when we start our
+Entering the command `i().` will show the running processes, including
+one called `hello_erlang_sup`. This is the supervisor for our
-:: Setting up Cowboy
+The release currently does nothing. In the rest of this chapter we
+will add Cowboy as a dependency and write a simple "Hello world!"
-Cowboy does nothing by default.
+:: Cowboy setup
-Cowboy uses Ranch for handling the connections and provides convenience
-functions to start Ranch listeners.
+To add Cowboy as a dependency of your application, we need to modify
+two files: the Makefile and the application resource file.
-The `cowboy:start_http/4` function starts a listener for HTTP connections
-using the TCP transport. The `cowboy:start_https/4` function starts a
-listener for HTTPS connections using the SSL transport.
+Modifying the Makefile allows the build system to know it needs to
+fetch and compile Cowboy. To do that we simply need to add one line
+to our Makefile to make it look like this:
-Listeners are a group of processes that are used to accept and manage
-connections. The processes used specifically for accepting connections
-are called acceptors. The number of acceptor processes is unrelated to
-the maximum number of connections Cowboy can handle. Please refer to
-the ^"Ranch guide^http://ninenines.eu/docs/en/ranch/HEAD/guide/
-for in-depth information.
-Listeners are named. They spawn a given number of acceptors, listen for
-connections using the given transport options and pass along the protocol
-options to the connection processes. The protocol options must include
-the dispatch list for routing requests to handlers.
-The dispatch list is explained in greater details in the
-^"Routing^routing^ chapter. For the purpose of this example
-we will simply map all URLs to our handler `hello_handler`,
-using the wildcard `_` for both the hostname and path parts
-of the URL.
-This is what the `hello_erlang_app:start/2` function looks like
-with Cowboy initialized.
-``` erlang
-start(_Type, _Args) ->
- Dispatch = cowboy_router:compile([
- %% {URIHost, list({URIPath, Handler, Opts})}
- {'_', [{'_', hello_handler, []}]}
- ]),
- %% Name, NbAcceptors, TransOpts, ProtoOpts
- cowboy:start_http(my_http_listener, 100,
- [{port, 8080}],
- [{env, [{dispatch, Dispatch}]}]
- ),
- hello_erlang_sup:start_link().
+``` Makefile
+PROJECT = hello_erlang
+DEPS = cowboy
+include erlang.mk
-Do note that we told Cowboy to start listening on port 8080.
-You can change this value if needed.
+Modifying the application resource file, `src/hello_erlang.app.src`,
+allows the build system to know it needs to include Cowboy in the
+release and start it automatically. This is a different step because
+some dependencies are only needed during development.
-Our application doesn't need to start any process, as Cowboy
-will automatically start processes for every incoming
-connections. We are still required to have a top-level supervisor
-however, albeit a fairly small one.
+We are simply going to add `cowboy` to the list of `applications`,
+right after `stdlib`. Don't forget the comma separator.
``` erlang
-start_link() ->
- supervisor:start_link({local, ?MODULE}, ?MODULE, []).
-init([]) ->
- {ok, {{one_for_one, 10, 10}, []}}.
+{application, hello_erlang, [
+ {description, "Hello Erlang!"},
+ {vsn, "0.1.0"},
+ {modules, []},
+ {registered, []},
+ {applications, [
+ kernel,
+ stdlib,
+ cowboy
+ ]},
+ {mod, {hello_erlang_app, []}},
+ {env, []}
-Finally, we need to write the code for handling incoming requests.
-:: Handling HTTP requests
-Cowboy features many kinds of handlers. For this simple example,
-we will just use the plain HTTP handler, which has three callback
-functions: `init/3`, `handle/2` and `terminate/3`. You can find more
-information about the arguments and possible return values of these
-callbacks in the
-^"cowboy_http_handler function reference^http://ninenines.eu/docs/en/cowboy/HEAD/manual/cowboy_http_handler^.
-Our handler will only send a friendly hello back to the client.
-``` erlang
-init(_Type, Req, _Opts) ->
- {ok, Req, undefined_state}.
-handle(Req, State) ->
- {ok, Req2} = cowboy_req:reply(200, [
- {<<"content-type">>, <<"text/plain">>}
- ], <<"Hello World!">>, Req),
- {ok, Req2, State}.
-terminate(_Reason, _Req, _State) ->
- ok.
+You may want to set a description for the application while you
+are editing the file.
-The `Req` variable above is the Req object, which allows the developer
-to obtain information about the request and to perform a reply.
-Its usage is documented in the
-^"cowboy_req function reference^http://ninenines.eu/docs/en/cowboy/HEAD/manual/cowboy_req^.
+If you run `make` now and start the release, Cowboy will be included
+and started automatically. This is not enough however, as Cowboy
+doesn't do anything by default. We still need to tell Cowboy to
+listen for connections.
-The code for our application is ready, so let's build a release!
+:: Listening for connections
-:: Compiling
+We will do this when our application starts. It's a two step process.
+First we need to define and compile the dispatch list, a list of
+routes that Cowboy will use to map requests to handler modules.
+Then we tell Cowboy to listen for connections.
-First we need to download `erlang.mk`.
+Open the `src/hello_erlang_app.erl` file and add the necessary
+code to the `start/2` function to make it look like this:
-``` bash
-$ wget https://raw.github.com/extend/erlang.mk/master/erlang.mk
-$ ls
+``` erlang
+start(_Type, _Args) ->
+ Dispatch = cowboy_router:compile([
+ {'_', [{"/", hello_handler, []}]}
+ ]),
+ cowboy:start_http(my_http_listener, 100, [{port, 8080}],
+ [{env, [{dispatch, Dispatch}]}]
+ ),
+ hello_erlang_sup:start_link().
-Then we need to create a Makefile that will include `erlang.mk`
-for building our application. We need to define the Cowboy
-dependency in the Makefile. Thankfully `erlang.mk` already
-knows where to find Cowboy as it features a package index,
-so we can just tell it to look there.
+The dispatch list is explained in great details in the
+^"Routing^routing^ chapter. For this tutorial we map the
+path `/` to the handler module `hello_handler`. This module
+doesn't exist yet, we still have to write it.
-``` Makefile
-PROJECT = hello_erlang
+If you build the release, start it and open ^http://localhost:8080
+now, you will get an error because the module is missing. Any
+other URL, like ^http://localhost:8080/test^, will result in a
+404 error.
-DEPS = cowboy
-dep_cowboy = pkg://cowboy master
-include erlang.mk
+:: Handling requests
-Note that when creating production nodes you will most likely
-want to use a specific version of Cowboy instead of `master`,
-and properly test your release every time you update Cowboy.
+Cowboy features different kinds of handlers, including REST
+and Websocket handlers. For this tutorial we will use a plain
+HTTP handler.
-If you type `make` in a shell now, your application should build
-as expected. If you get compilation errors, double check that you
-haven't made any typo when creating the previous files.
+First, let's generate a handler from a template.
``` bash
-$ make
+$ make new t=cowboy_http n=hello_handler
-:: Generating the release
-That's not all however, as we want to create a working release.
-For that purpose, we need to create a `relx.config` file. When
-this file exists, `erlang.mk` will automatically download `relx`
-and build the release when you type `make`.
-In the `relx.config` file, we only need to tell `relx` that
-we want the release to include the `hello_erlang` application,
-and that we want an extended start script for convenience.
-`relx` will figure out which other applications are required
-by looking into the `.app` files for dependencies.
+You can then open the `src/hello_handler.erl` file and modify
+the `handle/2` function like this to send a reply.
``` erlang
-{release, {hello_erlang, "1"}, [hello_erlang]}.
-{extended_start_script, true}.
+handle(Req, State=#state{}) ->
+ {ok, Req2} = cowboy_req:reply(200,
+ [{<<"content-type">>, <<"text/plain">>}],
+ <<"Hello Erlang!">>,
+ Req),
+ {ok, Req2, State}.
-The `release` value is used to specify the release name, its
-version, and the applications to be included.
-We can now build and start the release.
-``` bash
-$ make
-$ ./_rel/hello_erlang/bin/hello_erlang console
+What the above code does is send a `200 OK` reply, with the
+`content-type` header set to `text/plain` and the response
+body set to `Hello Erlang!`.
-If you then access `http://localhost:8080` using your browser,
-you should receive a nice greet!
+If you build the release, start it and open ^http://localhost:8080
+in your browser, you should get a nice `Hello Erlang!` displayed!