ruby-on-rails-3 – Rails respond_with – 为什么POST返回一个URL而不是数据?

前端之家收集整理的这篇文章主要介绍了ruby-on-rails-3 – Rails respond_with – 为什么POST返回一个URL而不是数据?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这是一个问题,“为什么这样做”,而不是“我如何做这个工作”.

我的应用程序正在调用返回JSON的第三方REST API,并将结果作为我自己的JSON API的一部分返回.

我正在使用Rails 3 respond_to和respond_with方法;在GET请求的情况下,这可以像我预期的那样工作,只是传递JSON.

在POST的情况下,它会执行更多操作,包括从返回的对象中创建一个URL以传递:location选项.但是由于我的对象只是JSON(不是ActiveRecord),所以我收到一个错误.

例如…

# POST /api/products.json with params id=:id
def create
  query_string = "#{user_id}&id=#{params[:id]}"
  @products = third_party_api_wrapper.products(query_string,'POST')
  respond_with @products
end

我的第三方API的包装器发出了一个POST请求,这回来了,然后Rails返回一个500错误,记录如下:

NoMethodError (undefined method `{"response":{"message":"product 4e1712d9ec0f257c510013f8 selected"}}_url' for #<MyController>

Rails希望我的@products对象知道如何创建位置URL.

澄清:第三方API返回的@products对象是纯JSON – 一个字符串,您可以在上面的错误日志消息中看到它.发生这个错误是因为Rails似乎希望对象更多 – 在Rails内部API支持中,它是一个ActiveRecord对象.

如果我用旧样式替换新的respond_with与sytax

respond_to do |format|
  format.json { render :json => @products }  # note,no :location or :status options
end

那么一切都行.这就是我所做的,所以我没有一个“怎样”的问题,而是有一个“为什么”的问题.

Ryan Daigle’s post的介绍解释了预期会发生什么.

我的问题是:为什么respond_with期望除了数据之外的任何东西(和HTTP状态?),而且显然只是为了POST.

我不是说这是错误的,只是想了解Rails实现的理由.

解决方法

总结:Rails从HTTP和REST获得理由.

(感谢您的更新问题,现在我了解您的核心问题:“我不是说错了,只是想了解Rails实现的基本原理.”)

现在为了解释. Rails行为方式的理由植根于拥抱HTTP和REST约定.

只要从你所读到的内容中填补我要阐述的内容,我想从Ryan Daigle’s article on Default RESTful Rendering提到相关的部分:

If the :html format was requested:

[some text removed]

  • [after PUT or POST and no validation errors] redirect to the resource location (i.e. user_url)

(我已经添加了[括号中的]文字.)

If another format was requested,(i.e. :xml or :json)

[some text removed]

  • If it was a POST request,invoke the :to_format method on the resource and send that back with the :created status and the :location of the new created resource”

让我用我的话说出Rails认为是好的做法:

>对于人类内容(例如HTML),在POST或PUT之后,服务器应该告诉浏览器通过303重定向到新创建的资源.这是常见的做法 – 一个非常有用的事情,因为用户希望看到他们编辑所产生的更新.
>对于机器内容(例如JSON,XML),在PUT之后,服务器应该只渲染一个201.客户端,在这种情况下是一个消耗API的程序,可能会决定停止. (毕竟,客户端指定了请求并获得了201,所以都是愚蠢的dory.)这就是为什么使用201(成功)而不是303(重定向).如果客户端想要请求新创建的资源,它可以使用Location头找到它,但不应强制重定向.

在任一情况下,请注意,新创建的资源的位置是必需的.这就是为什么上面的例子中的@products需要包含数据和位置.

对于背景,我从W3C Page on 201 Created分享了一点:

10.2.2 201 Created

The request has been fulfilled and resulted in a new resource being created. The newly created resource can be referenced by the URI(s) returned in the entity of the response,with the most specific URI for the resource given by a Location header field. The response SHOULD include an entity containing a list of resource characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. The origin server MUST create the resource before returning the 201 status code. If the action cannot be carried out immediately,the server SHOULD respond with 202 (Accepted) response instead.

我希望这有助于解释理由.我的(天真的)理解是,这种理由在Web框架中被广泛接受.历史上,我怀疑Rails是REST和面向资源架构的许多热心支持者的热切实施(新词警戒!).

原文链接:https://www.f2er.com/ruby/273303.html

猜你在找的Ruby相关文章