REST API implementation using Yaws

六月ゝ 毕业季﹏ 提交于 2019-12-22 10:13:06

问题


I'm trying to build a REST API using the Yaws web server but I'm unable to get Yaws to dispatch requests to my module.

-module(rest).
-include_lib("stdlib/include/qlc.hrl").
-include_lib("yaws/include/yaws_api.hrl").
-export([out/1, addAirport/4, handle/2]).
-compile(export_all).

-define(RECORD_TYPE, airport).
-define(RECORD_KEY_FIELD, code).

-record(airport,
        {code, city, country, name }).

start() ->
    application:start(mnesia).

do_this_once() ->
    mnesia:create_table(airport, [{attributes,record_info(fields,airport)},{index, [country]}]),
    mnesia:stop().

out(Arg) ->
    Method = method(Arg) ,
    io:format("~p:~p ~p Request ~n", [?MODULE, ?LINE, Method]),
    handle(Method, Arg).

method(Arg) ->
    Rec = Arg#arg.req,
    Rec#http_request.method.

convert_to_json(Lines) ->
    Data = [{obj, [{airport, Line#?RECORD_TYPE.code},
                   {city, Line#?RECORD_TYPE.city},
                   {country, Line#?RECORD_TYPE.country},
                   {name, Line#?RECORD_TYPE.name}]} || Line <- Lines],
    JsonData = {obj, [{data, Data}]},
    rfc4627:encode(JsonData).

addAirport(Code, City, Country, Name) ->
    NewRec = #?RECORD_TYPE{?RECORD_KEY_FIELD = Code,
                           city = City,
                           country = Country,
                           name = Name},
    io:format("~p:~p Adding Airport ~p~n",
              [?MODULE,?LINE, NewRec]),
    Add = fun() ->
                  mnesia:write(NewRec)
          end,
    {atomic, _Rec} = mnesia:transaction(Add),
    NewRec.

handle('GET', _Arg) ->
    io:format("~n ~p:~p GET Request ~n", [?MODULE, ?LINE]),
    Records = do(qlc:q([X || X <- mnesia:table(?RECORD_TYPE)])),
    Json = convert_to_json( Records),
    io:format("~n ~p:~p GET Request Response ~p ~n", [?MODULE, ?LINE,
                                                      Json]),
    {html, Json};
handle('POST', Arg) ->
    {ok, Json, _} = rfc4627:decode(Arg#arg.clidata),
    io:format("~n~p:~p POST request ~p~n",
              [?MODULE, ?LINE, Json]),
    Airport = rfc4627:get_field(Json, "airport", <<>>),
    City = rfc4627:get_field(Json, "city", <<>>),
    Country = rfc4627:get_field(Json, "country", <<>>),
    Name= rfc4627:get_field(Json, "name", <<>>),
    _Status = addAirport(Airport, City, Country, Name),
    [{status, 201},
     {html, Arg#arg.clidata}];
handle('PUT', Arg) ->
    [IndexValue,_] = string:tokens(Arg#arg.pathinfo),
    {ok, Json, _} = rfc4627:decode(Arg#arg.clidata),
    io:format("~p:~p PUT request ~p ~p~n",
              [?MODULE, ?LINE, IndexValue, Json]),
    Airport = rfc4627:get_field(Json, "airport", <<>>),
    City = rfc4627:get_field(Json, "city", <<>>),
    Country = rfc4627:get_field(Json, "country", <<>>),
    Name= rfc4627:get_field(Json, "name", <<>>),
    NewRec = #?RECORD_TYPE{
                 ?RECORD_KEY_FIELD = Airport,
                 city = City,
                 country = Country,
                 name = Name},
    io:format("~p:~p Renaming ~p",
              [?MODULE, ?LINE, NewRec]),
    ChangeName = fun() ->
                         mnesia:delete(
                           {?RECORD_KEY_FIELD, IndexValue}),
                         mnesia:write(NewRec)
                 end,
    {atomic, _Rec} = mnesia:transaction(ChangeName),
    [{status, 200},
     {html, IndexValue}];

handle('DELETE', Arg) ->
    [IndexValue, _ ] = string:tokens(Arg#arg.pathinfo),
    io:format("~p:~p DELETE request ~p",
              [?MODULE, ?LINE, IndexValue]),
    Delete = fun() ->
                     mnesia:delete(
                       {?RECORD_KEY_FIELD, IndexValue})
             end,
    Resp = mnesia:transaction(Delete),
    case Resp of
        {atomic, ok} ->
            [{status, 204}];
        {_, Error} ->
            io:format("~p:~p Error ~p ",
                      [?MODULE, ?LINE, Error]),
            [{status, 400},
             {html, Error}]
    end;
handle(Method,_) ->
    [{error, "Unknown method " ++ Method},
     {status, 405},
     {header, "Allow: GET, HEAD, POST, PUT, DELETE"}
    ].

do(Q)->
    F = fun() ->
                qlc:e(Q)
        end,
    {atomic, Value} = mnesia:transaction(F),
    Value.

回答1:


You need to register your module as a Yaws appmod in the server configuration portion of your yaws.conf file. Please see the Yaws appmod documentation for the necessary details.



来源:https://stackoverflow.com/questions/23290224/rest-api-implementation-using-yaws

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!