假设我有一个具有名称和年龄属性的ruby模型。使用rails generate scaffold
时,对这些对象之一的GET请求会返回类似这样的内容:
{
"id": 1,
"name": "foo",
"age": 21,
"parent_id": 1
}
默认情况下,此资源的POST / PUT需要:
{
"user": {
"name": "foo",
"age": 21,
"parent_id": 1
}
}
使用路由中配置的嵌套资源时,默认行为是将父ID添加到此嵌套哈希之外,例如:PUT /parents/1/users
:
{
"parent_id": 1,
"user": {
"name": "foo",
"age": 21
}
}
我可以简单地转到控制器并改变预期的参数,但我想知道为什么会这样,如果我改变它就冒险破坏任何东西。
更具体地说,这是一个Rails API,我想在API中添加swagger doc生成,因此拥有这个不对称的请求体是令人讨厌的。
总而言之,我的问题是:
POST /parents/1/users
这样的调用时,我最好/应该如何使API自动添加父ID,因为再次默认生成不支持它,我想知道是否有原因这有什么好处?
这可能是基于意见的答案,StackOverflow通常不赞成,但这是我的2美分。
在GET请求中,您只是返回一个资源。所以你需要知道的属性:
{
"id": 1,
"name": "foo",
"age": 21,
"parent_id": 1
}
另一方面,对于这个PUT
请求:
{
"parent_id": 1,
"user": {
"name": "foo",
"age": 21
}
}
您可以将参数视为分为两个“部分”:parent_id
(通常作为path
param发送,而不是请求体的一部分!)是“搜索/过滤”的东西,而user
params是要更新的user
资源的属性。
这种关注点的逻辑分离在Web表单(Rails最初/主要是为其设计)的上下文中特别有用,尤其是在处理复杂查询或“嵌套”属性时。
通过改变它有什么风险?
真的没什么。
但是,该格式针对RESTful API和Web表单的上下文进行了“优化”。
如果您更愿意使用其他格式,那么请继续; Rails并没有强迫你在这里使用任何东西。请注意,一个天真的“更好的设计”可能会回来咬你。
如何最好地以一种没有不同的GET响应而不是PUT / POST的方式为API添加swagger支持(对我来说这似乎是糟糕的设计,但也许我错了)?
您可以按照自己喜欢的方式设计API。如果你想在任何地方使用“平面参数”,那么只需构建这样的Rails应用程序。
在进行像POST / parents / 1 / users这样的调用时,我最好/应该如何使API自动添加父ID,因为再次默认生成不支持它,我想知道是否有原因
我不确定你的意思是“默认代不支持它”。默认生成什么?昂首阔步的文件?铁轨应用?
无论如何......那应该作为路径参数来实现。昂首阔步的文档看起来像这样:
/parents/{parent_id}/users:
get:
description: '.....'
parameters:
- name: parent_id
in: path
description: 'ID of the parent'
required: true
type: integer
Tom Lord的回答和说明可能比我的好。
我的猜测是,这模仿了HTTP的行为。如果你获取数据,你可以添加参数(?name=foo
)。但是,如果您POST数据,则倾向于将有效负载放在请求的正文中。并且URL中没有任何参数。
很可能Rails认为您将把JSON对象放入请求的主体中。而GET请求它将分开键/值并作为参数发送。