RESTful API - 在请求中传递虚假/未请求参数时的正确行为

时间:2013-12-11 18:11:01

标签: api validation rest request http-status-code-400

我们正在开发一个RESTful api,它以JSON编码数据的形式接受请求中的查询参数。

我们想知道非请求/非预期参数与所需参数一起传递时的正确行为。

例如,我们可能要求给定端点上的PUT请求必须分别为键名称姓氏提供两个值:

{
    "name": "Jeff",
    "surname": "Atwood"
}

如果虚假键也被传递,如下例中的颜色,该怎么办?

{
    "name": "Jeff",
    "surname": "Atwood",

    "color": "red"
}

颜色的值不是预期的,也没有记录。

我们应该忽略它还是拒绝BAD_REQUEST 400状态错误的请求?

我们可以断言请求是坏的,因为它不符合文档。可能API用户应该被警告(她传递了价值,她会期待一些东西。)

但我们也可以断言请求可以被接受,因为,因为所有参数都已提供,所以可以实现。

6 个答案:

答案 0 :(得分:34)

多年来使用过来自众多供应商的RESTful API,让我给你一个“用户”的观点。

很多时候,文档很糟糕或过时了。可能参数名称已更改,也许您在属性名称上强制使用了完整的大小写,也许您在文档中使用了错误的字体,并且 I 看起来与 l 完全相同 - 是的,那些是不同的字母。

不要忽略它。而是发回错误消息,说明属性名称,并带有易于理解的消息。例如“未知属性名称:颜色”。

这一小事将大大限制消耗API的支持请求。

如果您只是忽略这些参数,那么开发人员可能会认为在引用您的API时传入了有效值,因为显然 API无法正常工作。

如果你抛出一般性错误消息,那么你就会让开发人员试图找出正在发生的事情并充斥你的论坛,这个网站或你的手机会打电话询问为什么你的服务器无法工作。 (我最近遇到了这个问题,供应商只是不明白404消息不是对错误参数的有效响应,而且文档应该反映使用的实际参数名称......)

现在,出于同样的原因,我希望您在缺少必需参数时也能提供良好的错误消息。例如“必需属性:名称缺失”


基本上,您希望尽可能提供帮助,以便API的使用者尽可能自给自足。正如你所言,我全心全意地不同意“亲切”与“严厉”的崩溃。您越“亲切”,您的API消费者就越有可能遇到他们认为他们正在做正确的事情但却从您的API中获得意外行为的问题。你无法想到人们会搞砸所有可能的方式,所以强制严格遵守相关的错误信息将会有很大的帮助。

答案 1 :(得分:17)

如果您进行API设计,您可以遵循两条路径:“严厉”或“亲切”。

  • 严厉意味着:如果你做了什么我没想到我会生你的气。
  • 亲切的意思是:如果我知道你想要什么并且能够实现它,我就会这样做。

REST允许一个非常优雅的API设计,我会尝试尽可能长时间地遵循这条路径并期望我的客户一样。如果我的API发展,我可能必须在我的响应中添加仅与特定客户相关的其他参数。如果我的客户对我很慷慨,他们将能够处理这个问题。 话虽如此,我想补充说,有一个严格的API设计的地方。如果您在敏感域(例如现金交易)中进行设计,并且您不希望为客户端和服务器之间的任何误解留出空间。想象一下以下POST请求(对您的/ account / {no} / transaction / API有效):

{ amount: "-100", currency : "USD" }

您将如何处理以下(无效的API请求)?

{ amount: "100", currency : "USD", type : "withdrawal" }

如果您只是忽略“类型”属性,您将存入100美元而不是取消它们。在这样的领域,我会遵循严厉的方法,并且不会表现出任何优雅。

如果可以的话,请保持仁慈,如果必须,请严厉。

<强>更新

我完全同意@Chris Lively's answer应告知用户。我不同意它应该始终是一个错误的情况,即使消息对于引用的资源是非模糊的。否则,这将阻碍资源表示的重用,并需要重新打包语义相同的信息。

答案 2 :(得分:0)

请忽略它们。

不要让用户有机会通过错误消息对RESTful API进行反向工程。

为开发人员提供最新,最清晰,最全面的文档,并仅解析API所需和支持的参数。

答案 3 :(得分:0)

这取决于你的文件..你想要多严格..
但一般来说,只是ignore它。大多数其他服务器也忽略它不理解的请求参数。

从我之前的帖子中取得的例子

Extra Query parameters in the REST API Url

“”“Google在此忽略我的两个额外参数https://www.google.com/#q=search+for+something&invalid=param&more=stuff”“”

答案 4 :(得分:0)

想象一下,我有以下JSON架构:

{
   "frequency": "YEARLY",
   "date": 23,
   "month": "MAY",
}

frequency属性接受“WEEKLY”,“MONTHLY”和“YEARLY”值。 “WEEKLY”频率值的预期有效载荷是:

{
   "frequency": "WEEKLY",
   "day": "MONDAY",
}

“MONTHLY”频率值的预期有效载荷是:

{
   "frequency": "MONTHLY",
   "date": 23,
}

给出上面的JSON模式,通常我需要一个包含频率,日期,日期和月份字段的POJO来进行反序列化。

如果收到的有效载荷是:

{
   "frequency": "MONTHLY",
   "day": "MONDAY",
   "date": 23,
   "year": 2018
}

我会在“day”属性上抛出错误,因为我永远不会知道发件人的意图:

  1. 频率:“每周”和日期:“星期一”(输入的频率值不正确)或
  2. 频率:“每月”和日期:23
  3. 对于“年”属性,我真的没有选择。 即使我希望为该属性抛出错误,我也许无法做到。 它被JSON序列化/反序列化库忽略,因为我的POJO没有这样的属性。这是GSON的行为,鉴于设计决策,它是有意义的。

      

    在反序列化时导航Json树或目标类型树

         

    当您将Json字符串反序列化为所需类型的对象时,您可以导航输入树或所需类型的类型树。 Gson使用后一种方法来导航目标对象的类型。这使您可以严格控制仅实例化您期望的对象类型(实质上根据预期的“模式”验证输入)。通过这样做,您还可以忽略Json输入但不期望的任何额外字段。

         

    作为Gson的一部分,我们编写了一个通用的ObjectNavigator,可以接受任何对象并在其字段中导航,调用您选择的访问者。

    摘自GSON Design Document

答案 5 :(得分:-1)

我建议您忽略额外的参数。重用API是整合世界中的游戏规则改变者。如果其他集成可以使用相同的API,但有一些额外的参数,该怎么办?

申请A期待:

{
    "name": "Jeff",
    "surname": "Atwood"
}

申请B期待:

{
    "name": "Jeff",
    "surname": "Atwood",
    "color": "red"
}

简单获取应用程序应用程序A忽略“颜色”将完成工作而不是有2个不同的API来处理它。