RESTful ПОЛОЖИТЬ, если не существует?

#http #rest #put

#http #отдых #положить

Вопрос:

Допустим, я создаю RESTful интерфейс, и я хочу загрузить ресурс с помощью PUT to /resources/{id} . Но я хочу загружать вещь только в том случае, если она не была загружена ранее.

Я понимаю, что PUT это должно быть идемпотентным, поэтому, если я PUT что-то дважды отправляю на один и тот же URL, это должно быть успешным оба раза, верно?

Я также понимаю, что я мог бы использовать HEAD на существующем ресурсе, а затем использовать ETag to в my PUT , чтобы убедиться, что ресурс не был изменен с момента последней проверки.

Но как я могу гарантировать, что я загружаю объект только в том случае, если объект еще не существует? То есть, как я могу убедиться, что я не наступаю на чужую вещь?

Ответ №1:

Я понимаю, что PUT должен быть идемпотентным, поэтому, если я помещу что-то дважды в один и тот же URL, оно должно быть успешным оба раза, верно?

Правильно.

Но как я могу гарантировать, что я загружаю объект только в том случае, если объект еще не существует? То есть, как я могу убедиться, что я не наступаю на чужую вещь?

Не используйте вызов HEAD. Сделайте вызов PUT, используя заголовок If-None-Match: * . Это даст указание серверу выполнять операцию только в том случае, если текущий объект не существует, как подробно описано в пункте 3 RFC 2616.

Ответ №2:

См . http://greenbytes.de/tech/webdav/rfc7232.html#rfc.section.3.2.p.7:

«If-None-Match также может использоваться со значением «*», чтобы предотвратить непреднамеренное изменение существующего представления целевого ресурса небезопасным методом запроса (например, PUT), когда клиент считает, что ресурс не имеет текущего представления (раздел 4.2.1 [RFC7231]). Это вариант проблемы «потерянного обновления», которая может возникнуть, если несколько клиентов пытаются создать начальное представление для целевого ресурса. «