Как установить код статуса в REST POST в Cowboy

Как я могу установить код состояния в моем ресурсе REST POST.

Сейчас я делаю это

make_post(Req, State) ->
  lager:info("post"),
  Resp = cowboy_req:set_resp_body(<<"HELLO POST\n">>, Req),
  {ok, Resp3} = cowboy_req:reply(201, Resp),
  {true, Resp3, State}.

Но получаю такие ошибки:

1: 43: 10.510 [info] [nonode @ nohost # pbshare_logic_registration # ‹0.205.0>] [handle_info # 35]: выйти из логики‹ 0.204.0> Причина: {function_clause, [{cowboy_req, reply, [204, [ ], ‹< >>, {http_req, # Port ‹0.6355>, ranch_tcp, keepalive,‹ 0.204.0>, ‹< "POST" >>, 'HTTP / 1.1', {{127,0,0,1} , 50024}, ‹< "localhost" >>, undefined, 8080, ‹* "/ rest / registration / make" >>, [‹* "make" >>], ‹* >>, undefined, [], [ {‹< "user-agent" >>, ‹* "curl / 7.29.0" >>}, {‹< "host" >>, ‹* "localhost: 8080" >>}, {‹< "accept" >>, ‹< "/" >>}, {‹< "content-type" >>, ‹* "application / json" >>}, {‹< "content-length"> , 14}, {‹< "content-type" >>, {‹< "application" >>, ‹************************************************************************************************************************************************************************************************************************************************************************************* }, {‹< "if-none-match" >>, undefined}, {‹< "if-unmodified-Since" >>, undefined}, {‹< "if-match" >>, undefined}, {‹ ‹" Accept ">>, [{{‹<" ">>, ‹**" >>, []}, 1000, []}]}], undefined, [{charset, undefined}, {media_type, {‹< "application" >>, ‹< "json" >>, []}}], готово, undefined, ‹< >>, false, готово, [], ‹< >>, undefined}], [{fil e, "src / cowboy_req.erl"}, {line, 948}]}, {cowboy_rest, response, 3, [{file, "src / cowboy_rest.erl"}, {line, 1085}]}, {cowboy_rest, обновление, 4, [{file, "src / cowboy_rest.erl"}, {line, 75}]}, {cowboy_protocol, execute, 4, [{file, "src / cowboy_protocol.erl"}, {line, 523} ]}]} 21: 43: 10.510 [ошибка] [Undefined # Undefined # emulator] [Undefined # Undefined]: Ошибка в процессе ‹0.204.0> со значением выхода: {function_clause, [{cowboy_req, reply, [204, [ ], ‹---------------- 0 байт >>, {http_req, # Порт ‹0.6355>, ranch_tcp, keepalive,‹ 0.204.0>, ‹< 4 байта >>, 'HTTP / 1.1', {{127,0,0,1 }, 50024}, ‹---------------- 9 байт >>, undefined, 8080, ‹› 23 байта >>, [‹› 4 байта >>], ‹---------------- 0 байт >>, undefined, [], [{‹› 10 байт >>, ‹---------------- 11 байтов >>}, {‹---------------- 4 байта >>, ‹---------------- 14 байтов >>}, {‹---------------- 6 байтов >>, ‹---------------- 3 байта >>}, {‹---------------- 12 байтов >> , ‹---------------- 16 байт >>}, {‹› 14 байт >>, ‹› 2 байта >>}], [{‹› 14 байт >>, 14}, {‹› 6 байт >>, undefined}, { ‹$ 14 байт >>, 14}, {‹› 12 байт >>, {‹› 11 байт >>, ‹---------------- 4 байта >>, []}}, {‹› 17 байт >>, undefined}, { ‹< 13 байт >>, undefined}, {‹< 19 байт >>, undefined}, {‹< 8 байт >>, undefined ...

Похоже, что после моего ответа ковбой снова пытается отправить ответ. Но у меня не было другого метода в API, который может изменить код состояния.


person Max Grigoriev    schedule 10.06.2013    source источник
comment
Что в вашем коде делает set_response_body? Должен ли он делать то же самое, что и cowboy_req: set_response_body / 2?   -  person mbesso    schedule 11.06.2013
comment
да, есть Resp3 = cowboy_req: set_resp_body (‹< HELLO POST \ n ››, Req)   -  person Max Grigoriev    schedule 11.06.2013
comment
Я не совсем понимаю, о чем вы говорите, что делает ваш set_response_body - вы не против добавить его в свой вопрос?   -  person jtmoulia    schedule 11.06.2013
comment
Я изменил свой вопрос и добавил cowboy_req: set_resp_body.   -  person Max Grigoriev    schedule 11.06.2013


Ответы (2)


Правильное решение - вернуть not {true, Resp3, State}. но {halt, Resp3, State}. В этом случае ковбой не продолжает обработку запроса.

person Max Grigoriev    schedule 12.06.2013
comment
Это прямо указано в документации. Почему бы не отметить свой ответ как принятый? И, возможно, завершите ответ отрывком: все обратные вызовы также могут возвращать {halt, Req, State}, чтобы остановить выполнение запроса, после чего будет вызван rest_terminate / 2. (и исправление опечаток и т. д.). - person Eric Platon; 16.10.2013

Обработчик отдыха Cowboy попытается установить код состояния ответа в соответствии с возвращаемыми значениями функций обратного вызова (см. http://ninenines.eu/docs/en/cowboy/HEAD/guide/rest_handlers).

Чтобы указать, что ресурс был создан (возвращая 201), вам, следовательно, необходимо реализовать обратный вызов для resource_exists в дополнение к функции создания тела. Вам также нужно будет указать URL-адрес вновь созданного ресурса в функции создания тела.

Вот что, я думаю, сработает для вас (не забудьте экспортировать resource_exists, иначе будет использоваться функция по умолчанию):

resource_exists(Req, State) ->
    {false, Req, State}.

make_post(Req, State) ->
    Req2 = cowboy_req:set_resp_body(<<"Hello world">>, Req),
    {{true, "/foo/bar"}, Req2, State}.
person mbesso    schedule 11.06.2013
comment
201 - это просто пример. У нас разные статусы в устаревшей системе, и я хотел бы иметь такое же поведение. - person Max Grigoriev; 12.06.2013
comment
Правильно, тогда вы правы в своем первоначальном предположении, что кажется, что ковбой пытается отправить ответ еще раз после моего ответа. Cowboy перезапишет данные, заданные с помощью cowboy_req: reply, на основе результатов обратных вызовов rest. cowboy_req: reply не отправляет никакого ответа сам по себе, он просто манипулирует внутренним состоянием обработчика отдыха. Ответ не отправляется, пока вся обработка не будет завершена (т.е. все обратные вызовы не будут выполнены), если какой-либо ответ обратного вызова не указывает на ошибку, возвращая остановку. - person mbesso; 12.06.2013
comment
mbesso, спасибо за ваш ответ, он действительно помог мне реализовать создание канонического ресурса с помощью метода PUT. - person skanatek; 23.12.2014