REST设计 - 具有多个可能的非成功有效负载的操作

时间:2014-05-21 04:47:50

标签: rest

我正在尝试为具有一堆业务规则的“添加人”操作设计REST方法。有多种可能的非成功有效载荷(用于商业目的),需要定义的结构(允许消费者解析细节)。

对于“添加一个人”,可能会发生以下不成功之一:

  1. 我们相信系统已经有了人。
    • 有效负载:该人的ID
  2. 有一些可能的比赛。
    • 有效负载:可能重复的列表,以及用于提交“肯定”记录的覆盖代码
  3. 一般验证错误
    • Payload:'Error'对象的数组。 (API的标准)
  4. 问题 - 回复对象

    如果他们都要在一个HTTP错误状态代码下返回,那么拥有一个不同的对象是否正确:

    • OverrideCode(for(1))
    • PersonPossibleMatches [](也适用于(1))
    • PersonDuplicateId(for(2))
    • ErrorList [](for(3))

    让消费者+文档解释解释?

    问题 - 回复代码

    400(错误请求)是否正确(或足够正确)HTTP状态代码?我们主要用于现场验证(也是场景(3) - 只是想知道这样的业务规则/'中间状态'是否有任何不同。

    是否有更合适的代码来传播3x场景?并且有效载荷是否可以不同?

    感谢。

5 个答案:

答案 0 :(得分:3)

您需要考虑两个方面

  1. HTTP响应代码。
  2. 错误响应有效负载。
  3. 点号1相对简单。您有400个错误代码用于错误请求。 409用于冲突资源。到目前为止简单。

    现在让我们考虑你的场景:

      
        
    1. 我们相信系统已经有了人。   有效负载:该人的ID
    2.   

    设计建议:您可以发送如下的回复

    Response code: 409
    
    {
        "error_code": "resource_exists",
        "error_description": "Resource person with ID XXX already exists"
        "debug_info": "",
        "link" : [
            {
                "href": "http://host-name/persons/123456",
                "rel": "person"
            }
        ]
    }
    
    
    
    
    2. There are some possible matches.
        Payload: A list of possible duplicates, and an override code to submit the record 'for sure'
    

    设计建议: 在这种情况下 - 您可能希望使用PUT来覆盖资源。无需使用特殊代码。

    Response Code: 400
    {
        "error_code": "potential_duplicates",
        "error_description": "Potentially the resource is duplicate of one of the following. Please use PUT with the resource ID to update"
        "debug_info": "",
        "link" : [
            {
                "href": "http://host-name/persons/234",
                "rel": "person"
            },
                    {
                "href": "http://host-name/persons/456",
                "rel": "person"
            },
            {
                "href": "http://host-name/persons/789",
                "rel": "person"
            }
        ]
    }
    
      
        
    1. 一般验证错误   有效负载:错误数组'宾语。 (API的标准)
    2.   

    设计建议:在这里,你可以简单地使用400响应代码和一个有意义的响应,如上面的例子。

答案 1 :(得分:2)

您可以使用409作为重复条目 - 并且可以说是可能的重复条目以及有效负载中的额外信息。

http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10

400验证错误将是预期的响应。

在一天结束时这是一个判断电话,这取决于你的休息客户和他们正在做什么会更容易。

答案 2 :(得分:2)

以下是我为错误案例创建RESTful API响应时使用的设计过程:

  1. 设计错误条件的响应有效负载。无论使用何种错误代码,最好在错误响应中返回一些内容,以便客户可以了解错误以及将来如何避免错误。

  2. 如果存在准确描述此错误的HTTP状态代码,并且尚未将其用于其他错误情况,请使用该状态。

  3. 如果最接近的匹配错误代码已用于其他错误情况,则仍然可以使用该代码,但响应有效负载将成为该代码下的不同错误情况相互区分的位置。您的文档应明确说明检查此代码是不够的,然后客户端也应该查看响应以确切了解发生的情况。

  4. 如果以上都不适用,请使用最合适的最接近的错误代码。就像在#3中一样,响应有效负载的文档使这种方法成为可能。如果是客户端影响的错误,请将其设为400范围错误,可能为400 - Bad Request。如果是服务器的错误,那么它应该是500范围的错误,可能是500 - Internal Server Error

  5. ,不要因错误而抛出200 - OK。世界在肥皂土地上留下了废话,没有人愿意回去。

  6. 现在让我们将这种想法应用于您的错误案例:

    • We believe the system already has that person.正如另一个答案中所述,409 - Conflict准确地描述了该错误,因此您应该使用它。在响应有效负载中添加一些描述性错误信息将有助于API的新用户,即使有这样一个明确且易于理解的代码。

    • There are some possible matches.确实没有描述这个的HTTP代码,而且客户端可以影响它,所以最接近的是400 - Bad Request的全能代码。包括可能重复的列表是一个有趣的想法,但请确保您最终不会返回大量可能匹配的大量响应。此外,请确保还将URI返回给那些匹配的资源,以便您的客户可以轻松使用它们。至于“覆盖代码”建议,我不会在有效负载中返回。相反,我只是将一个参数记录到你的“添加一个人”操作,该操作允许在任何时候发生覆盖,而不仅仅是在第一次尝试失败之后。例如:POST /people?overwrite=true

    • General validation errors这绝对是400 - Bad Request的工作,以及描述性错误有效负载。听起来你已经允许从任何API调用返回一系列错误,因此它应该足以捕获客户端提供的数据的所有验证失败。

答案 3 :(得分:2)

这部分取决于操作的执行方式。既然你说操作有一堆业务规则,并且当人已经存在时系统返回带有ID的有效负载,那么我们假设由于不相关的副作用,操作是非幂等的,使用POST到工厂端点执行

<强> 1。我们认为该系统已有人。

这是一个明智的做法。正如其他人所建议的那样,您应该使用409 Conflict状态代码,并使用描述冲突性质的正文。在这种情况下,似乎没有其他用户需要做的事情,他可以继续前进到工作流程的下一步。如果他能做什么,它应该遵循类似于下一个案例的程序。

<强> 2。有一些可能的匹配。

假设客户没有明确识别某个人的任何密钥,这似乎是您的情况,因为您正在考虑可能的匹配,这里您还应该使用409 Conflict状态代码,带有正文描述冲突的性质,但有关于如何解决冲突的说明。

其他一些答案建议你允许一个可以随时使用的覆盖参数,其他建议使用PUT,但我不同意这一点,因为没有什么能阻止客户端一直使用覆盖,或者跳过POST并使用PUT替换现有的近似匹配。此外,您可能有并发客户端尝试添加或更改彼此匹配的人员或共同存在的组,这将导致ABA冲突。

冲突解决主体应为每个可能的匹配返回有效标记,并且应指示客户端使用If-Match标头和标记集合重新提交相同的请求。它可以是单个标记,只要它是从集合中每个成员的密钥数据生成的。这将强制用户首先必须尝试请求而不进行任何覆盖。如果存在冲突,则用户被迫指定将被覆盖的确切实体,并且如果某人更改了第一个和第二个请求之间的当前状态,则可以保护您免受不一致的更新。

如果第二个请求中的标记不匹配,意味着状态在它们之间被其他内容更改,则应该会出现412 Precondition Failed错误。

第3。一般验证错误

这也是一个明智的选择。 400 Bad Request详细说明了错误,这似乎是您的API的标准。

答案 4 :(得分:0)

如何用有效载荷来解释它;这就是我们如何处理客户的REST响应。

响应HTTP 409以及以下有效负载响应,向客户端指示他们接下来应该做什么 `

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<request-result>
<http-code>200</http-code>
<description>REST Request is successfully processed</description>
<internal-error-info>Person already Exists</internal-error-info>
<message>Person with <id> already exists in sytem. Try picking different ID/Name combination</message>
<requested-operation>Add a Person</requested-operation>
<resource-name>Person</resource-name>
<status>SUCCESSFUL</status>
</request-result>

`