Подтвердить что ты не робот

Rest api design: POST для создания с дублирующимися данными, будущий IntegrityError/500, что было бы правильно?

У меня нормальный базовый REST api вроде:

/
    GET - list
    POST - create

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

Когда POST входит в /, я обычно создаю объект и создаю новый идентификатор. Некоторый (один) из полей (is) должен быть уникальным. Таким образом, POST с такими дублирующимися данными может привести к:

  • 500 - IntegrityError
  • Сделайте его более похожим на PUT/PATCH на /<id> и обновите существующую запись
  • Поймать/избежать ошибки и вернуть какой-то 4XX
  • Что-то еще, о чем я не думаю.

1 кажется: запрос либо плох, либо я могу справиться с ним. Каков правильный способ справиться с этой ситуацией?

4b9b3361

Ответ 1

@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>

После управления гипермедиа и попытки создать пользователя с именем пользователя "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>

ПРИМЕЧАНИЕ. Соответствующий тип носителя должен быть создан, чтобы соответствовать приведенному выше, что объясняет структуру элементов управления гипермедиа (включая атрибуты ошибки на формы) и определить значение различных имен элементов (например, пользователей, имя пользователя, пароль и т.д.).

Ответ 2

# 3 более уместен. Ошибки 5xx - это когда что-то не так с сервером. Ошибки 4xx - это когда что-то не так с запросом. В этом случае запрос неверен, поэтому более подходящим является 4xx. Либо 400, либо 409.

Или вы можете сделать # 2, действительно зависит от контекста.