【问题标题】:Cowboy - REST callback isn't calledCowboy - 未调用 REST 回调
【发布时间】:2018-03-23 13:52:36
【问题描述】:

我正在尝试实现 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

我错过了什么?

【问题讨论】:

  • 如果您开始自己做某事会很好,当您遇到某事时,请特别询问它。
  • @ɐuıɥɔɐɯ 我改了问题,你能回答一下吗?

标签: rest erlang cowboy


【解决方案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,从现在开始,这个 handler 支持 JSON 响应。这就是为什么当您执行GET 时,您将成功获得HTTP 200 (OK)...但POST 不起作用。

另一方面,content_types_accepted 回调允许声明 content-types 接受什么。您确实可以发送POST 请求,因为您在allowed_methods 回调中添加了&lt;&lt;"POST"&gt;&gt;,但这将导致HTTP 415 (Unsupported Media Type) 响应,因为您没有告诉cowboy_rest 您想接受@ 987654338@.

这应该适合你:

-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
%%%==============================================

【讨论】:

  • 非常感谢!这是合乎逻辑的,让我感到羞耻......我是 Erlang 的新手,但对它充满热情。
猜你喜欢
  • 2018-02-09
  • 2021-11-13
  • 2015-12-08
  • 2013-03-15
  • 2018-05-01
  • 1970-01-01
  • 2017-04-07
相关资源
最近更新 更多