How to add Nitrogen and Cowboy as dependency libs to your erlang application

I received several emails asking to give the steps how to add Nitrogen and Cowboy as dependency libs to an application. The similar questions came up few times in the past on the Nitrogen mailing list. I posted a while ago how to use Nitrogen / Mochiweb / Webmachine but since then I moved to using Cowboy as the underlying http server for Nitrogen.

Cowboy has several important features:

  • the project has an active development community and it is still in active development stage.
  • it is highly optimized for speed and memory use and code base is very clean and doesn’t use process dictionaries and parametrized modules.
  • It provides the REST API on top of http protocol similar to the one pioneered by Webmachine.
  • Cowboy has a native supports for Websockets.

So, Cowboy combines in a single package http server / page router / websockets support and provides a similar features set as Mochiweb / Webmachine or Yaws.

I like this because Cowboy is definitely lighter that Yaws and faster than Mochiweb.

The installation steps:

1. Add the Simple_Bridge / Cowboy / Nitrogen_Core / Nprocreg / Sync into your rebar.config:

{lib_dirs,["deps"]}.
{src_dirs, ["src"]}.
{erl_opts, [debug_info, fail_on_warning]}.

{deps, [
    {simple_bridge, ".*", {git, "git://github.com/RomanShestakov/simple_bridge", "HEAD"}},
    {cowboy, ".*", {git, "git://github.com/extend/cowboy", "HEAD"}},
    {nitrogen_core, ".*", {git, "git://github.com/nitrogen/nitrogen_core", "HEAD"}},
    {nprocreg,      ".*", {git, "git://github.com/nitrogen/nprocreg", "HEAD"}},
    {sync,          ".*", {git, "git://github.com/rustyio/sync", "HEAD"}},
]}.
{post_hooks, [{compile, "mkdir -p ./priv/static"},
	      {compile, "cp -R ./deps/nitrogen_core/www priv/static/nitrogen"}
	     ]}.

here I am using git://github.com/RomanShestakov/simple_bridge – this is simple_bridge bindings for newest version of Cowboy 0.8 which is not yet available in official Simple_Bridge repo.

Post_Hooks option creates “Static” dir under Priv and copies Nitrogen static files into this new directory.

2. in your .app file you need to start the following applications: [nprocreg, sync, crypto, ranch, cowboy]

-module(nitrogen_elements_examples_app).
-behaviour(application).
-export([
	 start/0,
	 start/2,
	 stop/1
	]).
-define(APPS, [nprocreg, sync, crypto, ranch, cowboy, nitrogen_elements_examples]).
start() ->
    [begin application:start(A), io:format("~p~n", [A]) end || A <- ?APPS].
start(_StartType, _StartArgs) ->
    nitrogen_elements_examples_sup:start_link().
stop(_State) ->
    ok.

3. in your supervisor file you need to start cowboy listener and configure the dispatch rules:

-module(nitrogen_elements_examples_sup).
-behaviour(supervisor).
-export([start_link/0,init/1]).
-compile(export_all).
-include_lib ("nitrogen_core/include/wf.hrl").
-define(APP, nitrogen_elements_examples).

start_link() ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, []).

init([]) ->
    {ok, Port} = application:get_env(port),
    io:format("Starting Cowboy Server ~p ~n", [Port]),
    {ok, _} = cowboy:start_http(http, 100,
				[{port, Port}],
				[{env, [{dispatch, dispatch_rules()}]}]),
    {ok, {{one_for_one, 5, 10}, []}}.

dispatch_rules() ->
    cowboy_router:compile(
	%% {Host, list({Path, Handler, Opts})}
	[{'_', [
	    {["/static/[...]"], cowboy_static, [{directory, {priv_dir, ?APP, [<<"static">>]}},
		{mimetypes, {fun mimetypes:path_to_mimes/2, default}}]},
	    {'_', nitrogen_cowboy, []}
    ]}]).

here we are saying that request which start with “static” in the path will be redirected to cowboy_static handler – this handler comes with Cowboy installation and will serve static files from your application priv_dir.

All other requests will be redirected to nitrogen_cowboy handler – this handler will serve your dynamic html generated by Nitrogen.

-module(nitrogen_cowboy).
-behaviour(cowboy_http_handler).
-include_lib("nitrogen_core/include/wf.hrl").
-export([init/3, handle/2, terminate/3]).

-record(state, {headers, body}).

init(_Transport, Req, Opts) ->
    {ok, Req, #state{}}.

handle(Req, State) ->
    RequestBridge = simple_bridge:make_request(cowboy_request_bridge, Req),
    ResponseBridge = simple_bridge:make_response(cowboy_response_bridge, RequestBridge),
    nitrogen:init_request(RequestBridge, ResponseBridge),
    {ok, NewReq} = nitrogen:run(),
    {ok, NewReq, State}.

terminate(_Reason, _Req, _State) ->
    ok.

These are all the steps that you need to be able to add Nitrogen and Cowboy as dependencies libs to your application and automatically upload them from github repos.

You can find a full example here.

Advertisements
This entry was posted in Cowboy, Erlang, Nitrogen, Simple_Bridge and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s