为什么rails POST / PUT格式默认与GET不同?

问题描述 投票:2回答:2

假设我有一个具有名称和年龄属性的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生成,因此拥有这个不对称的请求体是令人讨厌的。

总而言之,我的问题是:

  • 这有什么好处,为什么它是Rails默认值,我通过更改它有什么风险?
  • 如何最好地以一种没有不同的GET响应而不是PUT / POST的方式为API添加swagger支持(对我来说这似乎是糟糕的设计,但也许我错了)?
  • 在进行像POST /parents/1/users这样的调用时,我最好/应该如何使API自动添加父ID,因为再次默认生成不支持它,我想知道是否有原因
ruby-on-rails ruby swagger
2个回答
0
投票

这有什么好处?

这可能是基于意见的答案,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

0
投票

Tom Lord的回答和说明可能比我的好。


我的猜测是,这模仿了HTTP的行为。如果你获取数据,你可以添加参数(?name=foo)。但是,如果您POST数据,则倾向于将有效负载放在请求的正文中。并且URL中没有任何参数。

很可能Rails认为您将把JSON对象放入请求的主体中。而GET请求它将分开键/值并作为参数发送。

  • 保持它的方式的优点是它将避免以后的陷阱。我认为这在编程中总是最好的,但也特别像Rails。但是,如果您正在制作API,我可以看到为什么您希望让人们将数据作为参数而不是需要验证的正文发送。
  • 至于Swagger,让用户知道他们需要将数据作为JSON字符串发送,然后按预期使用参数功能。
  • 最后一个有点棘手。我想这取决于你的API的设计。您可以将其作为请求的一部分传递。也许看看像RESTful API Design这样的东西来澄清你的目标。
© www.soinside.com 2019 - 2024. All rights reserved.