REST - Как запрос PUT будет обрабатывать автоматически увеличивающиеся идентификаторы ресурсов

Согласно HTTP 1.1. спецификация:

Если Request-URI не указывает на существующий ресурс, и этот URI может быть определен как новый ресурс запрашивающим пользовательским агентом, исходный сервер может создать ресурс с этим URI.

Другими словами, PUT можно использовать для создания и обновления. В частности, если я делаю запрос PUT, например.

PUT /users/1

и этот пользователь не существует, я ожидаю, что в результате этого запроса будет создан пользователь с этим идентификатором. Однако как это будет работать, если ваш сервер использует ключ автоинкремента? Будет ли это случай простого игнорирования, если это невозможно (например, автоинкремент равен 6, а я запрашиваю 10) и создания, если это возможно (например, запрос 7)?

Из фрагмента, который я извлек выше, кажется, что он дает вам эту гибкость, просто ищу некоторые разъяснения.


person James    schedule 26.03.2012    source источник


Ответы (2)


Я бы посоветовал вам использовать POST, а не PUT, для ключа автоинкремента или не использовать ключ автоинкремента в идентификаторе ресурса.

Если вы используете POST, вы должны отправить POST на /users, а не на /users/1. Ответ может перенаправить вас на /users/1 или любой другой идентификатор.

Если вы используете PUT, то вы можете PUT использовать /users/10292829, где число — это уникальный ключ ресурса, сгенерированный на клиенте. Этот ключ может быть сгенерирован по времени или может представлять собой хэш времени, идентификатор сеанса и некоторые другие факторы, чтобы гарантировать уникальность значения для вашей клиентской аудитории. Затем сервер может сгенерировать свой собственный автоматически увеличивающийся индекс, отличный от 10292829 или чего-то еще.

Подробнее об этом см. в разделе PUT и POST в REST.


Следование. . .

В случае разрешения PUT для /users/XXXXXXX для всех пользователей вы получите два разных уникальных ключа, которые относятся к одному и тому же ресурсу. (10292829 и 1 могут относиться к одному и тому же пользователю). Вам нужно будет решить, как разрешить использование каждого из этих разных ключей в URL-адресе в стиле REST. Из-за необходимости согласовать использование этих двух разных идентификаторов я бы предпочел использовать первый вариант, POST для /users и получения уникального URL-адреса REST созданного ресурса в ответе.

Я только что перечитал соответствующий раздел RFC 2616 и увидел код возврата, специально разработанный для этого в приложениях REST:

10.2.2 201 Создано

Запрос был выполнен, и в результате был создан новый ресурс. На вновь созданный ресурс можно ссылаться по URI, возвращаемому в объекте ответа, причем наиболее конкретный URI для ресурса указывается в поле заголовка Location. Ответ ДОЛЖЕН включать сущность, содержащую список характеристик ресурсов и местоположений, из которых пользователь или пользовательский агент может выбрать наиболее подходящий. Формат объекта определяется типом носителя, указанным в поле заголовка Content-Type. Исходный сервер ДОЛЖЕН создать ресурс перед возвратом кода состояния 201. Если действие не может быть выполнено немедленно, сервер ДОЛЖЕН вместо этого ответить ответом 202 (принято).

Таким образом, способ RESTful — отправить POST на /users и вернуть 201 Created с заголовком Location:, указывающим /users/1.

person Cheeso    schedule 26.03.2012
comment
Мой REST API в настоящее время поддерживает POST, но я хочу также поддерживать PUT, чтобы разрешить обновления. Таким образом, чтобы избежать сложности передачи уникальных идентификаторов со стороны клиента, должен ли PUT просто возвращать 404, если ресурс не существует, а не пытаться его создать? Будет ли это по-прежнему считаться RESTful? - person James; 27.03.2012
comment
Да, PUT предназначен для обновлений. Если URI, на который отправляется PUT, не относится к доступному ресурсу, то разумно вернуть 404. Если это REST/JSON, вы можете включить сообщение об ошибке в формате json в тело сообщения ответа. {"error":"resource does not exist."}. Но на самом деле отправка информации в теле сообщения уместна только в том случае, если она дополняет информацию, которую передает код состояния. Если сообщение «Не существует», то достаточно 404, и тело сообщения не требуется. - person Cheeso; 27.03.2012
comment
Круто, так что действительно с PUT у вас есть выбор, хотите ли вы создавать или нет (это то, о чем я действительно искал разъяснений). Думаю, в моем сценарии PUT будет использоваться исключительно для обновления (если ресурс существует). Спасибо! - person James; 27.03.2012
comment
да, я думаю, что спецификация несколько открыта в отношении того, как именно следует использовать PUT. Но на практике я стараюсь спроектировать максимально простую модель. Для меня использование PUT для обновлений с указанием URL-адреса существующего ресурса имеет интуитивно понятный смысл; использование POST для создания, указание URL-адреса фабрики ресурсов или менеджера ресурсов и ответ 201 Created имеет смысл. - person Cheeso; 27.03.2012

Вы должны использовать POST для создания ресурсов, в то время как PUT следует использовать только для обновления. На самом деле семантика REST заставляет вас это делать.

person Ruwan    schedule 27.03.2012
comment
Согласно спецификации, PUT можно использовать для создания ресурсов в сценарии, когда ресурс по указанному URI не существует... это дилемма. - person James; 27.03.2012