Erlang牛仔约束编码

时间:2019-02-17 10:55:44

标签: erlang constraints handler cowboy

{"/:myobj/get:id",Constraints, constraints_handler, [list]},
{"/:myobj/list",Constraints, constraints_handler, [list]},
{"/:myobj/save",Constraints, constraints_handler, [save]},
{"/:myobj/update",Constraints, constraints_handler, [update]},
{"/:myobj/delete",Constraints, constraints_handler, [delete]}

请帮助我编写约束条件,其中:myobj将是没有空格和特殊字符的字符串值。和:id将为int。

1 个答案:

答案 0 :(得分:0)

hello_erlang_app.erl

-module(hello_erlang_app).
-behaviour(application).

-export([start/2]).
-export([stop/1]).
-export([positive_fun/2]).

positive_fun(forward, Value) when Value > 0 -> 
    {ok, Value};
positive_fun(forward, _) ->
    {error, not_positive}.
%Not for route constraints:
%positive_fun(format_error, {not_positive, Value}) ->
%    io_lib:format("The value ~p is not an integer.", [Value]).

convert(forward, Value) ->
    DecodedValue = cow_qs:urldecode(Value),
    NoSpaces = re:replace(DecodedValue, " ", "", [global, {return, list}]),
    {ok, NoSpaces}. 

start(_Type, _Args) ->
    MyObjConstraints = { myobj, [fun convert/2] },
    IdConstraints = { id, [int, fun positive_fun/2] },

    IdRoute = { "/:myobj/get/:id", 
                 [MyObjConstraints, IdConstraints],  
                 id_handler, 
                 []
              }, %The last arg becomes the State 
                 %arg in the id_handler's init() method.

    CatchallRoute = {"/[...]", no_matching_route_handler, []},

    Dispatch = cowboy_router:compile([
        {'_', [IdRoute, CatchallRoute]}
    ]), 

    {ok, _} = cowboy:start_clear(my_http_listener,
        [{port, 8080}],
        #{env => #{dispatch => Dispatch} }
    ),

    hello_erlang_sup:start_link().


stop(_State) ->
    ok.

id_handler.erl

-module(id_handler).
-behavior(cowboy_handler).

-export([init/2]).

init(Req0, State) -> %State comes from last argument of the route
    MyObj = cowboy_req:binding(myobj, Req0),
    Id = cowboy_req:binding(id, Req0),
    Reply = io_lib:format("Hello Erlang~nMyObj=~p~nId=~w~n", [MyObj, Id]),

    Req = cowboy_req:reply(200,
        #{<<"content-type">> => <<"text/plain">>},
        Reply,
        Req0),
    {ok, Req, State}.

no_matching_route_handler.erl

-module(no_matching_route_handler).
-behavior(cowboy_handler).

-export([init/2]).

init(Req0, State) -> %State comes from last argument of the route
    Req = cowboy_req:reply(404,
        #{<<"content-type">> => <<"text/plain">>},
        <<"[ME] 404. Whoops! (No matching route!)">>,
        Req0),
    {ok, Req, State}.

制作文件

PROJECT = hello_erlang
PROJECT_DESCRIPTION = New project
PROJECT_VERSION = 0.1.0

DEPS = cowboy
#dep_cowboy_commit = master
dep_cowboy_commit = 2.6.1


DEP_PLUGINS = cowboy

include erlang.mk

一些例子:

url in browser: http://localhost:8080/dog/get/1

response:

    Hello Erlang
    MyObj="dog"
    Id=1

url in browser: http://localhost:8080/dog/get/-4

response:

    [ME] 404. Whoops! (No matching route!)

url in browser: http://localhost:8080/h%20e%20l%20l%20o/get/1

response:

    Hello Erlang
    MyObj="hello"
    Id=1

url in browser: http://localhost:8080/hello%28%27arg%27%29/get/1

response:

    Hello Erlang
    MyObj="hello('arg')"
    Id=1

url in browser: http://localhost:8080/h%20e%20l%20l%20o%28%27arg%27%29/get/1

response:

    Hello Erlang
    MyObj="hello('arg')"
    Id=1