Rest api设计:使用重复数据创建POST,可能是IntegrityError / 500,什么是正确的?

时间:2021-09-29 22:26:19

I have a normal, basic REST api like:

我有一个正常的,基本的REST api,如:

/
    GET - list
    POST - create

/<id>
    GET - detail
    PUT - replace
    PATCH - patch
    DELETE - delete

When a POST comes in to /, I usually create an object and make a new id. Some (one) of the fields are (is) required to be unique. So, a POST with such duplicate data could result in:

当POST进入/时,我通常创建一个对象并创建一个新的id。某些(一个)字段必须是唯一的。因此,具有此类重复数据的POST可能会导致:

  1. 500 - IntegrityError
  2. 500 - IntegrityError
  3. Make it more like a PUT/PATCH to /<id> and update the existing record
  4. 使其更像是/ 的PUT / PATCH并更新现有记录
  5. Catch/avoid the error and return some sort of 4XX
  6. 捕获/避免错误并返回某种4XX
  7. Something else I'm not thinking of.
  8. 我还没想到的其他东西。

1 seems out: the request is either bad or I can deal with it. What is the correct way to handle this situation?

1似乎是:请求要么糟糕,要么我可以处理它。处理这种情况的正确方法是什么?

2 个解决方案

#1


17  

@StevenFisher is correct. 409 Conflict is the correct response.

@StevenFisher是对的。 409冲突是正确的答案。

The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required.

由于与资源的当前状态冲突,无法完成请求。只有在预期用户可能能够解决冲突并重新提交请求的情况下,才允许使用此代码。响应主体应该包含足够的信息供用户识别冲突的来源。理想情况下,响应实体将包含足够的信息供用户或用户代理解决问题;但是,这可能是不可能的,也不是必需的。

For instance, a GET on / might tell a client that they can create users as follows

例如,GET on /可能会告诉客户他们可以按如下方式创建用户

HTTP/1.1 200 OK
<users href="/">
    <create href="/" method="post">
        <username type="xs:token" cardinality="required"/>
        <password type="password" cardinality="required"/>
    </create>
    ... other hypermedia controls, like search ...
</users>

Following the hypermedia control and trying to create a user with the username "Skylar Saveland" might result in

遵循超媒体控制并尝试使用用户名“Skylar Saveland”创建用户可能会导致

HTTP/1.1 409 Conflict
<users href="/">
    <create href="/" method="post">
        <username type="xs:token" cardinality="required" 
                  error="The username 'Skylar Saveland' is already taken. Please select another username"/>
        <password type="password" cardinality="required"/>
    </create>
    ... other hypermedia controls, like search ...
</users>

Similarly, trying to create a user without a password might result in

同样,尝试创建没有密码的用户可能会导致

HTTP/1.1 409 Conflict
<users href="/">
    <create href="/" method="post">
        <username type="xs:token" cardinality="required"/>
        <password type="password" cardinality="required" 
                  error="A password must be specified"/>
    </create>
    ... other hypermedia controls, like search ...
</users>

or you might have multiple errors, e.g.,

或者您可能有多个错误,例如,

HTTP/1.1 409 Conflict
<users href="/">
    <create href="/" method="post">
        <username type="xs:token" cardinality="required"
                  error="The username 'Skylar Saveland' is already taken. Please select another username"/>
        <password type="password" cardinality="required"
                  error="A password must be specified"/>
    </create>
    ... other hypermedia controls, like search ...
</users>

NOTE: An appropriate media type will need to be created to go along with the above, which will explain the structure of the hypermedia controls (including the error attributes on the forms) and define the meaning of the various element names (e.g., users, username, password, etc).

注意:需要创建适当的媒体类型以配合上述内容,这将解释超媒体控件的结构(包括表单上的错误属性)并定义各种元素名称的含义(例如,用户,用户名,密码等)。

#2


1  

#3 is more appropriate. 5xx errors are when there's something wrong with the server. 4xx errors are when something is wrong with the request. In this case, the request is wrong, so a 4xx is more appropriate. Either a 400 or 409.

#3更合适。 5xx错误是指服务器出现问题。 4xx错误是指请求出现问题时。在这种情况下,请求是错误的,因此4xx更合适。 400或409。

Or you can do #2, really depends on the context.

或者你可以做#2,真的取决于上下文。

#1


17  

@StevenFisher is correct. 409 Conflict is the correct response.

@StevenFisher是对的。 409冲突是正确的答案。

The request could not be completed due to a conflict with the current state of the resource. This code is only allowed in situations where it is expected that the user might be able to resolve the conflict and resubmit the request. The response body SHOULD include enough information for the user to recognize the source of the conflict. Ideally, the response entity would include enough information for the user or user agent to fix the problem; however, that might not be possible and is not required.

由于与资源的当前状态冲突,无法完成请求。只有在预期用户可能能够解决冲突并重新提交请求的情况下,才允许使用此代码。响应主体应该包含足够的信息供用户识别冲突的来源。理想情况下,响应实体将包含足够的信息供用户或用户代理解决问题;但是,这可能是不可能的,也不是必需的。

For instance, a GET on / might tell a client that they can create users as follows

例如,GET on /可能会告诉客户他们可以按如下方式创建用户

HTTP/1.1 200 OK
<users href="/">
    <create href="/" method="post">
        <username type="xs:token" cardinality="required"/>
        <password type="password" cardinality="required"/>
    </create>
    ... other hypermedia controls, like search ...
</users>

Following the hypermedia control and trying to create a user with the username "Skylar Saveland" might result in

遵循超媒体控制并尝试使用用户名“Skylar Saveland”创建用户可能会导致

HTTP/1.1 409 Conflict
<users href="/">
    <create href="/" method="post">
        <username type="xs:token" cardinality="required" 
                  error="The username 'Skylar Saveland' is already taken. Please select another username"/>
        <password type="password" cardinality="required"/>
    </create>
    ... other hypermedia controls, like search ...
</users>

Similarly, trying to create a user without a password might result in

同样,尝试创建没有密码的用户可能会导致

HTTP/1.1 409 Conflict
<users href="/">
    <create href="/" method="post">
        <username type="xs:token" cardinality="required"/>
        <password type="password" cardinality="required" 
                  error="A password must be specified"/>
    </create>
    ... other hypermedia controls, like search ...
</users>

or you might have multiple errors, e.g.,

或者您可能有多个错误,例如,

HTTP/1.1 409 Conflict
<users href="/">
    <create href="/" method="post">
        <username type="xs:token" cardinality="required"
                  error="The username 'Skylar Saveland' is already taken. Please select another username"/>
        <password type="password" cardinality="required"
                  error="A password must be specified"/>
    </create>
    ... other hypermedia controls, like search ...
</users>

NOTE: An appropriate media type will need to be created to go along with the above, which will explain the structure of the hypermedia controls (including the error attributes on the forms) and define the meaning of the various element names (e.g., users, username, password, etc).

注意:需要创建适当的媒体类型以配合上述内容,这将解释超媒体控件的结构(包括表单上的错误属性)并定义各种元素名称的含义(例如,用户,用户名,密码等)。

#2


1  

#3 is more appropriate. 5xx errors are when there's something wrong with the server. 4xx errors are when something is wrong with the request. In this case, the request is wrong, so a 4xx is more appropriate. Either a 400 or 409.

#3更合适。 5xx错误是指服务器出现问题。 4xx错误是指请求出现问题时。在这种情况下,请求是错误的,因此4xx更合适。 400或409。

Or you can do #2, really depends on the context.

或者你可以做#2,真的取决于上下文。