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

Sky*_*and 13 api rest api-design http

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

/
    GET - list
    POST - create

/<id>
    GET - detail
    PUT - replace
    PATCH - patch
    DELETE - delete
Run Code Online (Sandbox Code Playgroud)

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

  1. 500 - IntegrityError
  2. 使它更像一个PUT/ PATCH/<id>和更新现有记录
  3. 捕获/避免错误并返回某种 4XX
  4. 还有别的我想不到的东西.

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

Tom*_*ard 17

@StevenFisher是对的.409冲突是正确的回应.

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

例如,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>
Run Code Online (Sandbox Code Playgroud)

遵循超媒体控制并尝试使用用户名"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>
Run Code Online (Sandbox Code Playgroud)

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

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>
Run Code Online (Sandbox Code Playgroud)

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

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>
Run Code Online (Sandbox Code Playgroud)

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