牛仔 - 没有召唤REST回调

时间:2017-10-11 19:11:06

标签: rest erlang cowboy

我试图实现Rest处理程序并拥有下一个代码:

-module(example_handler).
-behaviour(cowboy_handler).

-export([init/2,
         allowed_methods/2,
         content_types_provided/2,
         get_json/2]).

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

allowed_methods(Req, State) ->
    io:format("allowed_methods~n"),
    {[<<"GET">>, <<"POST">>], Req, State}.

content_types_provided(Req, State) ->
    io:format("content_types_provided~n"),
    {[{{<<"application">>, <<"json">>, []}, get_json}], Req, State}.

get_json(_Req, _State) ->
    io:format("get_json~n")

然后当我尝试像curl那样发送请求时:

curl -H "Accept: application/json" -X POST http://localhost:8080/xxx/xx

我得到下一个输出:

allowed_methods
content_types_provided

get_json()未被调用!但是当我使用GET方法时,一切看起来都很好:

curl -H "Accept: application/json" -X GET http://localhost:8080/xxx/xx
----------------------------------------------------------------------
allowed_methods
content_types_provided
get_json

我错过了什么?

1 个答案:

答案 0 :(得分:1)

<强> TL; DR

content_types_providedcontent_types_accepted不同;因为你正在处理POST,所以你需要更晚的。

在我使用的Cowboy 2.0.0中,content_types_provided回调按优先顺序返回资源提供的媒体类型列表。所以,当你使用:

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

你基本上告诉Cowboy,从现在开始,这个处理程序支持JSON响应。这就是为什么当您执行GET时,您将成功获得HTTP 200 (OK) ...但POST无法正常工作。

另一方面,content_types_accepted回调允许说明接受content-types的内容。您确实被允许发送POST个请求,因为您在<<"POST">>回调中添加了allowed_methods但这会导致HTTP 415 (Unsupported Media Type)响应,因为您还没有告诉cowboy_rest您要接受application/json

这应该对你有用:

-module(example_handler).

-export([init/2]).

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

-export([get_json/2, post_json/2]).

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

allowed_methods(Req, State) ->
  lager:debug("allowed_methods"),
  {[<<"GET">>, <<"POST">>], Req, State}.

content_types_accepted(Req, State) ->
  lager:debug("content_types_accepted"),
  {[
    {{<<"application">>, <<"json">>, []}, post_json}
  ], Req, State}.

content_types_provided(Req, State) ->
  lager:debug("content_types_provided"),
  {[
    {{<<"application">>, <<"json">>, []}, get_json}
  ], Req, State}.

get_json(Req, State) ->
  lager:debug("get_json"),
  {<<"{ \"hello\": \"there\" }">>, Req, State}.

post_json(Req, State) ->
  lager:debug("post_json"),
  {true, Req, State}.

%%%==============================================
%%% Internal
%%%==============================================