PUT
Применение
Запрос PUT указывает серверу сохранить вложенное представление по указанному URI. Если ресурс уже существует, сервер заменяет всё его состояние новым представлением. Если по этому URI ресурса нет, сервер создаёт его.
Идемпотентность
PUT идемпотентен. Многократная отправка одного и того же запроса PUT приводит к тому же состоянию сервера, что и однократная отправка. Этим он отличается от POST, где повторные отправки создают дубликаты ресурсов или запускают обработку несколько раз.
Идемпотентность делает безопасным повтор PUT после сетевых сбоев. Клиент, не уверенный, дошёл ли предыдущий запрос, отправляет его снова, не рискуя получить непреднамеренные побочные эффекты.
Согласование содержимого
Сервер проверяет входящее представление на соответствие собственным ограничениям. Когда Content-Type соответствует ожиданиям, а содержимое корректно сформировано, сервер сохраняет ресурс и отвечает 201 Created для новых ресурсов либо 200 OK / 204 No Content для замен.
Если медиатип несовместим, сервер возвращает 415 Unsupported Media Type. Ответ 409 Conflict указывает на конфликт состояния, не связанный с типом содержимого, например на несовпадение версий.
PUT и POST
POST делегирует обработку целевому ресурсу. PUT задаёт точный URI, которому принадлежит представление. PUT к /articles/42 сохраняет статью по адресу /articles/42. POST к /articles просит коллекцию создать новую статью по URI, выбранному сервером.
PUT и PATCH
PUT заменяет ресурс целиком. PATCH применяет частичные изменения. Чтобы обновить одно поле с помощью PUT, нужно отправить полное представление. PATCH отправляет только изменения.
Создание ресурса
Клиент сохраняет текстовый файл по адресу /docs/setup.txt. Сервер создаёт ресурс и отвечает 201 Created.
Запрос
PUT /docs/setup.txt HTTP/1.1
Host: api.example.re
Content-Type: text/plain
Content-Length: 24
Install, configure, run.
Ответ
HTTP/1.1 201 Created
Location: /docs/setup.txt
Content-Length: 0
Замена ресурса
Клиент заменяет существующий JSON-ресурс по адресу /users/42. Сервер подтверждает обновление кодом 200 OK и возвращает сохранённое представление.
Запрос
PUT /users/42 HTTP/1.1
Host: api.example.re
Content-Type: application/json
Content-Length: 43
{"name":"Alice","email":"alice@example.re"}
Ответ
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 51
{"id":42,"name":"Alice","email":"alice@example.re"}
Условное обновление
Условный запрос с If-Match предотвращает перезапись ресурса, изменённого другим клиентом. Значение ETag гарантирует, что обновление применится только к ожидаемой версии.
Запрос
PUT /config/app.json HTTP/1.1
Host: api.example.re
Content-Type: application/json
If-Match: "a1b2c3"
Content-Length: 27
{"debug":false,"port":8080}
Ответ
HTTP/1.1 204 No Content
ETag: "d4e5f6"
CORS
Межсайтовые запросы PUT всегда вызывают предварительный запрос CORS. Браузер сначала отправляет запрос OPTIONS, чтобы убедиться, что сервер разрешает PUT для целевого ресурса.
Коды состояния ответа
201 Created означает, что сервер создал новый ресурс по целевому URI. Это применимо, когда ранее по этому адресу ресурса не существовало.
200 OK подтверждает, что существующий ресурс был заменён, и ответ содержит обновлённое представление в теле.
204 No Content подтверждает замену без тела ответа. Это обычная ситуация, когда клиенту не нужно получать сохранённое представление обратно.
412 Precondition Failed означает, что условие If-Match не выполнено. Значение ETag, предоставленное клиентом, не совпадает с текущей версией ресурса, поэтому сервер отклоняет обновление, чтобы не перезаписать изменения, сделанные другим клиентом.
409 Conflict сигнализирует о конфликте состояния на уровне приложения, не связанном с предусловиями, — например, о конфликте слияния содержимого или коллизии в системе контроля версий, которую клиенту нужно разрешить вручную.