Skip to content

Commit

Permalink
Update the example and its doc (taking static analysis into account)
Browse files Browse the repository at this point in the history
  • Loading branch information
paulo-ferraz-oliveira committed Jan 6, 2022
1 parent 944e9e9 commit ec2fe6f
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 136 deletions.
70 changes: 31 additions & 39 deletions example/README.md
Original file line number Diff line number Diff line change
@@ -1,72 +1,64 @@
# Cowboy Trails Example
# Cowboy Trails Basic Example

To try this example, you need `git` and `Erlang` in your PATH.

```erlang

rebar3 compile
```shell
$ rebar3 compile
```

To start the example server in a interactive way do this:
```erlang

rebar3 shell
```

## Handlers Description

if you run this `curl` command, you will see all trails description of this server.

```shell
$ rebar3 shell
```
curl -i http://localhost:8080/description

[#{constraints => [],
handler => cowboy_static,
metadata => #{get => #{desc => "Static Data"}},
options => {priv_dir,example,[],[{mimetypes,cow_mimetypes,all}]},
path_match => <<"/[...]">>},
#{constraints => [],
handler => example_echo_handler,
metadata => #{get => #{desc => "Gets echo var in the server"},
put => #{desc => "Sets echo var in the server"}},
options => [],
path_match => <<"/message/[:echo]">>},
#{constraints => [],
handler => example_description_handler,
## Handlers' Description

If you run this `curl` command, you will see all trails' description of this server.

```shell
$ curl -i http://localhost:8080/description
[#{constraints => [],handler => example_poor_kv_handler,
metadata =>
#{delete =>
#{'content-type' => "text/plain",
desc => "Unsets an env var in the server"},
get =>
#{'content-type' => "text/plain",
desc => "Gets en env var from the server"},
put =>
#{'content-type' => "text/plain",
desc => "Sets an env var in the server"}},
options => [],path_match => "/poor-kv/:key/[:value]"},
#{constraints => [],handler => example_description_handler,
metadata => #{get => #{desc => "Retrives trails's server description"}},
options => [],
path_match => <<"/description">>}]
options => [],path_match => <<"/description">>}]
```

## Poor-Man's Key-Value Store
## Poor Man's Key-Value Store

There is an additional endpoint that implement a really simple key-value store
that uses the application's env variable as its backend. It is possible to `PUT`,
There is an additional endpoint that implements a really simple key-value store
that uses the application's env. variable as its backend. It is possible to `PUT`,
`GET` and `DELETE` values in the following way:

```
```shell
$ curl -XPUT "localhost:8080/poor-kv/some-key/some-value" -H "content-type: text/plain"
some-value

$ curl -XGET "localhost:8080/poor-kv/some-key" -H "content-type: text/plain"
$ curl "localhost:8080/poor-kv/some-key" -H "content-type: text/plain"
some-value

$ curl -v -XGET "localhost:8080/poor-kv/non-existing-key" -H "content-type: text/plain"
$ curl -v "localhost:8080/poor-kv/non-existing-key" -H "content-type: text/plain"
...
< HTTP/1.1 404 Not Found
...

$ curl -v -XDELETE "localhost:8080/poor-kv/some-key" -H "content-type: text/plain"
...
< HTTP/1.1 204 No Content
...

$ curl -v -XDELETE "localhost:8080/poor-kv/some-key" -H "content-type: text/plain"
...
< HTTP/1.1 404 Not Found
...
Expand Down
1 change: 1 addition & 0 deletions example/_checkouts/trails
52 changes: 0 additions & 52 deletions example/elvis.config

This file was deleted.

26 changes: 24 additions & 2 deletions example/rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,32 @@
, strict_validation
, warn_export_vars
, warn_exported_vars
, warn_missing_spec
, warn_untyped_record
, debug_info]}.

%% == Dependencies ==

{deps, [{mixer, "0.1.5", {pkg, inaka_mixer}}]}.
{deps, [ {mixer, "1.2.0", {pkg, inaka_mixer}}
, trails % checked out
]}.
{project_plugins, [ rebar3_lint
, rebar3_hank
]}.

%% == Shell (for interactive example) ==

{shell, [ {apps, [cowboy, trails, example]}
, {config, "rel/sys.config"}
]}.

%% == Release (for CI) ==

{relx, [ {include_src, false}
, {extended_start_script, true}
, {release, {example, "0.1"}, [example, sasl]}
, {sys_config, "rel/sys.config"}
]}.

%% == Alias ==

{alias, [{test, [dialyzer, lint, hank]}]}.
17 changes: 14 additions & 3 deletions example/rebar.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
{"1.1.0",
[{<<"mixer">>,{pkg,<<"inaka_mixer">>,<<"0.1.5">>},0}]}.
{"1.2.0",
[{<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.8.0">>},1},
{<<"cowlib">>,{pkg,<<"cowlib">>,<<"2.9.1">>},2},
{<<"mixer">>,{pkg,<<"inaka_mixer">>,<<"1.2.0">>},0},
{<<"ranch">>,{pkg,<<"ranch">>,<<"2.0.0">>},1}]}.
[
{pkg_hash,[
{<<"mixer">>, <<"754630C0E60221B23E4D83ADF6E789A8B283855E23F9391EEC40980E6E800486">>}]}
{<<"cowboy">>, <<"F3DC62E35797ECD9AC1B50DB74611193C29815401E53BAC9A5C0577BD7BC667D">>},
{<<"cowlib">>, <<"61A6C7C50CF07FDD24B2F45B89500BB93B6686579B069A89F88CB211E1125C78">>},
{<<"mixer">>, <<"FC11970AE637FA3081F608A96BD67CA4442C7D7BF9C482E6DD26E6C4B517213D">>},
{<<"ranch">>, <<"FBF3D79661C071543256F9051CAF19D65DAA6DF1CF6824D8F37A49B19A66F703">>}]},
{pkg_hash_ext,[
{<<"cowboy">>, <<"4643E4FBA74AC96D4D152C75803DE6FAD0B3FA5DF354C71AFDD6CBEEB15FAC8A">>},
{<<"cowlib">>, <<"E4175DC240A70D996156160891E1C62238EDE1729E45740BDD38064DAD476170">>},
{<<"mixer">>, <<"FB2332717158BBA05CEE8A76CCA76C3E0BE0EAD8EC23EE2415EA9AE65D726A48">>},
{<<"ranch">>, <<"C20A4840C7D6623C19812D3A7C828B2F1BD153EF0F124CB69C54FE51D8A42AE0">>}]}
].
3 changes: 2 additions & 1 deletion example/src/example.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
{applications,
[kernel,
stdlib,
cowboy
cowboy,
trails
]},
{modules, []},
{mod, {example, []}},
Expand Down
24 changes: 13 additions & 11 deletions example/src/example.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
-export([stop/1]).
-export([start_phase/3]).

-behaviour(application).
-hank([{unnecessary_function_arguments, [{start_phase, 3}]}]).

%% application
%% @doc Starts the application
start() ->
Expand Down Expand Up @@ -38,16 +41,15 @@ start_phase(start_trails_http, _StartType, []) ->
Trails = trails:trails(Handlers) ++ [DescriptionTrail],
trails:store(Trails),
Dispatch = trails:single_host_compile(Trails),
RanchOptions = [{port, Port}],
CowboyOptions =
[
{env,
[
{dispatch, Dispatch}
]},
{compress, true},
{timeout, 12000}
],
CowboyOptions = #{ env => #{ dispatch => Dispatch
}
, request_timeout => 12000
},
{ok, _} =
cowboy:start_http(example_http, ListenerCount, RanchOptions, CowboyOptions),
cowboy:start_clear(example_http,
#{ socket_opts => [ {port, Port}
]
, num_acceptors => ListenerCount
},
CowboyOptions),
ok.
18 changes: 7 additions & 11 deletions example/src/example_default.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

-export(
[
init/3,
rest_init/2,
init/2,
content_types_accepted/2,
content_types_provided/2,
forbidden/2,
Expand All @@ -12,11 +11,8 @@
).

%% cowboy
init(_Transport, _Req, _Opts) ->
{upgrade, protocol, cowboy_rest}.

rest_init(Req, _Opts) ->
{ok, Req, #{}}.
init(Req, State) ->
{cowboy_rest, Req, State}.

content_types_accepted(Req, State) ->
{[{<<"text/plain">>, handle_put}], Req, State}.
Expand All @@ -29,10 +25,10 @@ forbidden(Req, State) ->

resource_exists(Req, State) ->
case cowboy_req:binding(key, Req) of
{undefined, Req1} -> {true, Req1, State};
{Key, Req1} ->
undefined -> {true, Req, State};
Key ->
case application:get_env(example, Key, undefined) of
undefined -> {false, Req1, State};
_ -> {true, Req1, State}
undefined -> {false, Req, State};
_ -> {true, Req, State}
end
end.
3 changes: 1 addition & 2 deletions example/src/example_description_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
-mixin([
{example_default,
[
init/3,
rest_init/2,
init/2,
content_types_accepted/2,
content_types_provided/2,
resource_exists/2
Expand Down
27 changes: 12 additions & 15 deletions example/src/example_poor_kv_handler.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
-mixin([
{example_default,
[
init/3,
rest_init/2,
init/2,
content_types_accepted/2,
content_types_provided/2,
resource_exists/2
Expand Down Expand Up @@ -41,27 +40,25 @@ allowed_methods(Req, State) ->

%% internal
handle_get(Req, State) ->
{Key, Req1} = cowboy_req:binding(key, Req),
Key = cowboy_req:binding(key, Req),
case application:get_env(example, Key, undefined) of
undefined ->
{ok, Req2} = cowboy_req:reply(404, Req1),
{halt, Req2, State};
{halt, cowboy_req:reply(404, Req), State};
Value ->
{Value, Req1, State}
{Value, Req, State}
end.

handle_put(Req, State) ->
{Key, Req1} = cowboy_req:binding(key, Req),
case cowboy_req:binding(value, Req1, undefined) of
{undefined, Req2} ->
{false, Req2, State};
{Value, Req2} ->
Key = cowboy_req:binding(key, Req),
case cowboy_req:binding(value, Req, undefined) of
undefined ->
{false, Req, State};
Value ->
application:set_env(example, Key, Value),
Req3 = cowboy_req:set_resp_body(Value, Req2),
{true, Req3, State}
{true, cowboy_req:set_resp_body(Value, Req), State}
end.

delete_resource(Req, State) ->
{Key, Req1} = cowboy_req:binding(key, Req),
Key = cowboy_req:binding(key, Req),
application:unset_env(example, Key),
{true, Req1, State}.
{true, Req, State}.

0 comments on commit ec2fe6f

Please sign in to comment.