Как установить тело в ответ Cowboy POST

#rest #http #erlang #cowboy

#rest #http #erlang #ковбой

Вопрос:

У меня есть простой обработчик Cowboy rest:

 -module(request_handler).
-export([
  init/2,
  allowed_methods/2,
  content_types_accepted/2,
  content_types_provided/2
]).

-export([
  json_request/2,
  json_response/2
]).

init(Req, Opts) ->
  {cowboy_rest, Req, Opts}.

allowed_methods(Req, State) ->
  {[<<"GET">>, <<"POST">>, <<"PATCH">>, <<"DELETE">>], Req, State}.

content_types_accepted(Req, State) ->
  {[
    {<<"application/json">>, json_request}
  ], Req, State}.

content_types_provided(Req, State) ->
  {[
    {<<"application/json">>, json_response}
  ], Req, State}.


json_request(Req, State) ->
  Resp = cowboy_req:set_resp_body(<<"{"a":"b"}">>, Req),
  cowboy_req:reply(201, Resp),
  {true, Resp, State}.

json_response(Req, State) ->
  {true, Req, State}.

  

Но, когда я отправляю http-запрос, в журнале появляется ошибка:

2020-09-17T19:35:58.305000 03:00 error: <0.231.0> [proc_lib:crash_report/4-525] crasher: initial call: cowboy_clear:connection_process/4, pid: <0.231.0>, registered_name: [], error: {function_clause,[cowboy_http,commands,[state,<0.189.0>,http,#Port<0.10>,ranch_tcp,undefined,#{connection_type => supervisor,env => #{dispatch => [{'_',[],[{[<<"api">>,<<"v.0.1">>,'...'],[],request_handler,#{}},{[<<"static">>,'...'],[],cowboy_static,{priv_dir,gateway,"./www/static",[{mimetypes,cow_mimetypes,all}]}},{'_',[],cowboy_static,{priv_file,gateway,"www/index.html"}}]}]},idle_timeout => infinity,inactivity_timeout => infinity},<<>>,#{},{{127,0,0,1},18780},{{127,0,0,1},8585},undefined,undefined,true,2,{ps_request_line,0},infinity,1,done,1000,[{stream,1,{cowboy_stream_h,{state,undefined,http,<0.232.0>,undefined,undefined,undefined,undefined,0,fin,<<"{rn "Name" : "Test 2"}rn">>,165,undefined,normal}},<<"POST">>,'HTTP/1.1',undefined,undefined,0,[]}],[{child,<0.232.0>,1,5000,undefined}]},1,[{response,200,#{<<"content-length">> => <<"9">>,<<"content-type">> => [<<"application">>,<<"/">>,<<"json">>,<<>>],<<"date">> => <<"Thu, 17 Sep 2020 16:35:57 GMT">>,<<"server">> => <<"Cowboy">>},<<"{"a":"b"}">>}]],[{file,"d:/gateway/_build/default/lib/cowboy/src/cowboy_http.erl"},{line,954}]},{cowboy_http,loop,1,[{file,"d:/gateway/_build/default/lib/cowboy/src/cowboy_http.erl"},{line,254}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,226}]}]}, ancestors: [<0.189.0>,<0.188.0>,ranch_sup,<0.113.0>], message_queue_len: 1, messages: [{'EXIT',<0.232.0>,normal}], links: [#Port<0.10>,<0.189.0>], dictionary: [], trap_exit: true, status: running, heap_size: 1598, stack_size: 28, reductions: 1505; neighbours:

Что я делаю не так? Я просмотрел примеры и примеры из Google. Я не понимаю, чем мой код отличается от примеров в Интернете.

Комментарии:

1. Я не уверен на 100%, но… похоже, вы отвечаете дважды. Вы пробовали возвращать {false, Resp, State} из json_request/2 ?

2. Нет, не пробовал. Спасибо. Я собираюсь попробовать сейчас.

3. {false, соответственно, State} из json_request/2 — не помогло.

Ответ №1:

Как указано в комментарии выше, я опубликовал ответ дважды. Ниже показано, как это должно быть:

 json_request(Req, State) ->
  Resp = cowboy_req:set_resp_body(<<"{"a":"b"}">>, Req),
  cowboy_req:reply(201, Resp),
  {stop, Resp, State}.
  

Большое вам спасибо за ваши полезные комментарии.