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

Posted

技术标签:

【中文标题】Rest api 设计:使用重复数据创建 POST,可能是 IntegrityError/500,啥是正确的?【英文标题】:Rest api design: POST to create with duplicate data, would-be IntegrityError/500, what would be correct?Rest api 设计:使用重复数据创建 POST,可能是 IntegrityError/500,什么是正确的? 【发布时间】:2012-09-21 10:25:35 【问题描述】:

我有一个普通的基本 REST api,例如:

/
    GET - list
    POST - create

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

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

    500 - 完整性错误 使其更像 PUT/PATCH/&lt;id&gt; 并更新现有记录 捕捉/避免错误并返回某种4XX 我没有想到的其他事情。

1 似乎出局了:请求要么是错误的,要么我可以处理。处理这种情况的正确方法是什么?

【问题讨论】:

我会选择 409,“冲突”。但我不打算断言这是“正确”的方式。 :) 【参考方案1】:

@StevenFisher 是正确的。 409 Conflict 是正确的回复。

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

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

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>

按照超媒体控制并尝试使用用户名“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>

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

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>

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

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>

注意:一个适当的media type will need to be created 与上述内容一起使用,它将解释超媒体控件的结构(包括表单上的错误属性)并定义各种元素名称的含义(例如,用户,用户名、密码等)。

【讨论】:

【参考方案2】:

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

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

【讨论】:

#2 不正确。不带 ID 的 POST不应用于更新请求。

以上是关于Rest api 设计:使用重复数据创建 POST,可能是 IntegrityError/500,啥是正确的?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 nodejs 创建 POST REST API? [复制]

使用 Jquery 从 REST API nodeJS 获取数据 [重复]

使用 post 创建一个到 REST API 的条目

Django REST framework框架之GET, POST, PUT, PATCH, DELETE等API请求接口设计

将雪花数据发送到 REST API (POST) 的方法

REST API 设计中的查找或创建习语?