我试图实现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
我错过了什么?
答案 0 :(得分:1)
<强> TL; DR 强>
content_types_provided
与content_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
%%%==============================================