2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

CowboyでGETとPOSTの値を扱ってみる

Last updated at Posted at 2018-08-19

HTTPではGETとPOST時に値を追加してリクエストすることがよくあります。ですので今回はGETとPOST時の値の取得の仕方について記載していきます。

はじめに

ErlangとCowboyの環境設定については以下の記事に記載しています。気になる方は参考にしてみてください。
CowboyでHello Worldのサンプルを動かしてみる

Cowboyでのハンドラーの設定

まずはちゃっちゃかとハンドラーの設定をします。

sandbox_app.erl
    Dispatch = cowboy_router:compile([
        {'_', [
            {"/get", get_handler, []},
            {"/post", post_handler, []}
        ]}
    ]),
    {ok, _} = cowboy:start_clear(http, [{port, 8010}], #{
        env => #{dispatch => Dispatch}
    }),

/getパスではget_handlerを、/postパスではpost_handlerを実行するようにします。
あとは8010ポートでリクエストを待ち受けるようにします。

GETでの値の取得

GETでリクエストが来た際に、値を取得します。今回はecho=[何かしら] でリクエストがくる想定で値を取得しています。まずは全体像になります。

get_handler.erl
init(Req0, Opts) ->
    Method = cowboy_req:method(Req0),
    #{echo := Echo} = cowboy_req:match_qs([{echo, [], undefined}], Req0),
    Req = echo(Method, Echo, Req0),
    {ok, Req, Opts}.

echo(<<"GET">>, undefined, Req) ->
    cowboy_req:reply(400, #{}, <<"Missing echo parameter.">>, Req);
echo (<<"GET">>, Echo, Req) ->
    cowboy_req:reply(200, #{
        <<"content-type">> => <<"text/plain; charset=utf-8">>
    }, Echo, Req);
echo (_, _, Req) ->
    cowboy_req:reply(405, Req).

Method = cowboy_req:method(Req0),でリクエストできたメソッドを取得します。ここで取得できるのはGETになる想定です。もしGET以外できた場合は405をレスポンスするようになっています。

#{echo := Echo} = cowboy_req:match_qs([{echo, [], undefined}], Req0),でリクエストされた値を取得します。第一引数にリクエストされてきたどの値を取得するかを決めます。{echo, [], undefined}ではechoのキーのものを取得するように設定されてます。もしechoがない場合はデフォルト値としてundefinedが返ります。

Req = echo(Method, Echo, Req0),で取得したリクエスト値を元にレスポンスを返します。

get_handler.erl
echo(<<"GET">>, undefined, Req) ->
    cowboy_req:reply(400, #{}, <<"Missing echo parameter.">>, Req);
echo (<<"GET">>, Echo, Req) ->
    cowboy_req:reply(200, #{
        <<"content-type">> => <<"text/plain; charset=utf-8">>
    }, Echo, Req);
echo (_, _, Req) ->
    cowboy_req:reply(405, Req).

echo関数内ではリクエストにechoのキーがあった場合は200のステータスで取得した値をBodyにセットしてレスポンスします。
もし、echoのキーがなかった場合は、400のステータスで"Missing echo parameter."をbodyにセットしてレスポンスします。

POSTでの値の取得

次はPOSTでのリクエスト値の取得方法になります。まじは全体像を。

post_handler.erl
init(Req0, Opts) ->
    Method = cowboy_req:method(Req0),
    HasBody = cowboy_req:has_body(Req0),
    Req = maybe_echo(Method, HasBody, Req0),
    {ok, Req, Opts}.

maybe_echo(<<"POST">>, true, Req0) ->
    {ok, PostValue, Req} = cowboy_req:read_urlencoded_body(Req0),
    Echo = proplists:get_value(<<"echo">>, PostValue, undefined),
    echo(Echo, Req);
maybe_echo(<<"POST">>, false, Req) ->
    cowboy_req:reply(400, #{}, <<"Missing body.">>, Req);
maybe_echo(_, _, Req) ->
    cowboy_req:reply(405, Req).

echo(undefined, Req) ->
    cowboy_req:reply(400, #{}, <<"Missing echo parameter.">>, Req);
echo(Echo, Req) ->
    cowboy_req:reply(200, #{
        <<"content-type">> => <<"text/plain; charset=utf-8">>
    }, Echo, Req).

Method = cowboy_req:method(Req0),はGETと同様、HTTPのメソッドを取得します。ここではPOSTがくる想定です。
HasBody = cowboy_req:has_body(Req0),でリクエストがBodyを持っているかどうかを判定しています。つまり、POSTリクエスト内に値があるかどうかをチェックしています。

post_handler.erl
maybe_echo(<<"POST">>, true, Req0) ->
    {ok, PostValue, Req} = cowboy_req:read_urlencoded_body(Req0),
    Echo = proplists:get_value(<<"echo">>, PostValue),
    echo(Echo, Req);
maybe_echo(<<"POST">>, false, Req) ->
    cowboy_req:reply(400, #{}, <<"Missing body.">>, Req);

上記のもので値が取得できたかどうかをチェックしてします。第二引数にcowboy_req:has_body(Req0)の結果が入りますので、リクエストに値が入ってた場合はtrue、入ってなかった場合はfalseのmaybe_echoが実行されます。
cowboy_req:has_body(Req0)がtrueの場合はBodyの値を取得します。
Echo = proplists:get_value(<<"echo">>, PostValue),でリクエスト内にechoのキーの値を取得します。

post_handler.erl
echo(undefined, Req) ->
    cowboy_req:reply(400, #{}, <<"Missing echo parameter.">>, Req);
echo(Echo, Req) ->
    cowboy_req:reply(200, #{
        <<"content-type">> => <<"text/plain; charset=utf-8">>
    }, Echo, Req).

最後に、echoキーがある場合はレスポンスのBodyにechoキーの値をセットします。
echoキーがなかった場合はデフォルト値のundefinedが第一引数にくるので、400のステータスでエラーを返します。

まとめ

GETとPOSTでの値が取得できるようになりました。これとDBとを組み合わせれば、DBから値の取得や追加、更新、削除処理とができるようになりますね。
ただ、POSTの値の取得の仕方がちょっと気にくわないかな、、、もう少しCowboyで取得を簡単にできれば嬉しいですね。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?