#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]). Это вариант проблемы «потерянного обновления», которая может возникнуть, если несколько клиентов пытаются создать начальное представление для целевого ресурса. «