I configure restful api using Cowboy. The main task is to use one handler for POST, GET, PUT, DELETE

My router looks like this:

start(_Type, _Args) -> Dispatch = cowboy_router:compile([ {'_', [ {"/api", handler, []}, {"/api/:id", handler, []} ]} ]), {ok, _} = cowboy:start_clear(http, 100, [{port, 8080}], #{ env => #{dispatch => Dispatch} }), api_sup:start_link(). 

The handler looks like this:

 -module(handler). -export([init/3, handle/2]). init(_Transport, Req, []) -> {ok, Req, undefined}. handle(Req, Opts) -> case cowboy_req:method(Req) of <<"POST">> -> Body = cowboy_req:has_body(Req), Req = postMethod(<<"POST">>, Body, Req), {ok, Req, Opts}; <<"GET">> -> #{id := Id} = cowboy_req:match_qs([{id, [], undefined}], Req), Req = getMethod(<<"GET">>, Id, Req), {ok, Req, Opts}; <<"PUT">> -> Body = cowboy_req:has_body(Req), Req = putMethod(<<"PUT">>, Body, Req), {ok, Req, Opts}; <<"DELETE">> -> #{id := Id} = cowboy_req:match_qs([{id, [], undefined}], Req), Req = deleteMethod(<<"DELETE">>, Id, Req), {ok, Req, Opts} end. postMethod(<<"POST">>, _Body, Req) -> cowboy_req:reply(200, #{<<"content-type">> => <<"application/json; charset=utf-8">>}, <<"{\"status\": \"POST\"}">>, Req). getMethod(<<"GET">>, _Id, Req) -> cowboy_req:reply(200, #{<<"content-type">> => <<"application/json; charset=utf-8">>}, <<"{\"status\": \"GET\"}">>, Req). putMethod(<<"PUT">>, _Body, Req) -> cowboy_req:reply(200, #{<<"content-type">> => <<"application/json; charset=utf-8">>}, <<"{\"status\": \"PUT\"}">>, Req). deleteMethod(<<"DELETE">>, _Id, Req) -> cowboy_req:reply(200, #{<<"content-type">> => <<"application/json; charset=utf-8">>}, <<"{\"status\": \"DELETE\"}">>, Req). 

but after successful compilation - I get an error when calling any method

"Failed to connect to localhost port 8080: Connection refused"

tell me where there may be a problem? Or maybe there is a working example?

  • Connection error corrected. But now the error 500 from a cowboy - Eugen Dubrovin

1 answer 1

The answer is found. Working code: (using the master version of Cowboy)

 -module(handler). -export([init/2]). -export([content_types_provided/2]). -export([content_types_accepted/2]). -export([allowed_methods/2]). -export([router/2]). init(Req, Opts) -> {cowboy_rest, Req, Opts}. allowed_methods(Req, State) -> {[<<"GET">>, <<"POST">>, <<"PUT">>, <<"DELETE">>], Req, State}. content_types_provided(Req, State) -> {[{<<"application/json">>, router}], Req, State}. content_types_accepted(Req, State) -> {[{<<"application/json">>, router}], Req, State}. router(Req, Opts) -> case cowboy_req:method(Req) of <<"POST">> -> {<<"{\"status\": \"POST\"}">>, Req, State}; <<"GET">> -> {<<"{\"status\": \"GET\"}">>, Req, State}; <<"PUT">> -> {<<"{\"status\": \"PUT\"}">>, Req, State}; <<"DELETE">> -> {<<"{\"status\": \"DELETE\"}">>, Req, State} end.