patch запрос что это
Разница (отличия) между PUT и PATCH в REST [дубликат]
Сообщество рассмотрело необходимость повторного открытия этого вопроса 1 месяц назад и оставило его закрытым:
Исходные причины закрытия не были исправлены
В чём отличия между этими методами? Оба производят обновления объектов.
3 ответа 3
PATCH используется для частичного изменения ресурса. PUT создает новый ресурс или заменяет представление целевого ресурса, данными представленными в теле запроса.
Иными словами, в PATCH вложенный объект содержит набор инструкций, описывающих, как ресурс, находящийся в данный момент на исходном сервере, должен быть модифицирован для создания новой версии. А в PUT содержится новая версия ресурса целиком.
Спецификации методов на английском: PUT, PATCH
По данному вопросу хорошая документация есть на developer.mozilla.org.
UPDATE
PATCH не является идемпотентным (одноитоговым), т.к. в него можно вставить инструкцию добавления элемента. Тогда повторный запрос добавит его еще раз. А вот PUT просто перезаписал бы ресурс целиком (снова), т.е повторный запрос не приводит к разным результатам. Другие примеры: GET запрос идемпотентный: сколько бы раз ты не запрашивал в Google некоторый запрос, Google вернет тебе тот же результат. POST не идемпотентный: он может вставлять в базу новую строку каждый раз.
(Rails) PATCH — новый базовый HTTP-метод для обновлений
HTTP-метод PUT предназначен для создания или замены ресурса по заданному URL. Возьмем, к примеру, файл. Когда вы загружаете файл в S3 по определенному URL, вы либо хотите создать его по тому адресу, либо заменить уже имеющийся там файл. Это PUT-запрос.
Далее представим веб-приложение, имеющее модель Invoice (счет), которая содержит флаг paid (оплачен?). Как установить значение этого флага в стиле RESTful? Установка paid=1 через PUT-запрос по адресу /invoices/:id не подойдет, т.к. такой запрос не обеспечит полной пересылки состояния счета.
С учетом ограничений методов GET, POST, PUT и DELETE, традиционным советом будет определить флаг оплаты в качестве отдельного ресурса. Тем самым вы определяете маршрут для установки paid=1 через PUT-запрос к /invoices/:id/paid. Вам придется поступить подобным образом, т.к. PUT не позволяет произвести лишь частичное обновление ресурса.
Давайте подумаем о самых обычных формах на обновление в типичном Rails-приложении. Как часто вы посылаете полное представление ресурса? Не всегда, быть может даже довольно редко в вашей практике. К примеру, временные метки created_at и updated_at обычно не управляются конечным пользователем, хотя зачастую они считаются принадлежащими ресурсу, который мапится на запись БД.
Ещё стоит учитывать, что PUT — идемпотентный метод. Вы должны быть готовы принять такой запрос сколь угодно много раз и каждый раз возвратить корректный ресурс. Такое нарушение привычной идиомы иногда случается, когда посредством вложенных атрибутов создаются дочерние ресурсы, приводящие к параллельному обновлению родительского.
Хотя теоретически ничто не препятствует применению PUT для пересылки частичных обновлений, но фактически семантика замены уже была учтена во время стандартизации HTTP. Метод PATCH был представлен в 1995 году, а позднее вошел в стандарты. PATCH — это метод, который не объявляется ни безопасным, ни идемпотентным, и позволяет производить полное или частичное обновление, возможно с побочным эффектом на смежные ресурсы.
На практике, как вы можете видеть, PATCH обычно в большей степени подходит для обновления ресурсов, чем PUT. В Ruby on Rails он естественным образом соотносится с методом update_attributes, который используется для обновления записей.
Тем самым, PATCH в Rails 4.0 выдвигается на первые роли.
Несмотря на серьезность изменений, мы планируем реализовать их так, чтобы сохранить обратную совместимость. Когда ресурс объявляется в routes.rb, например:
экшен на обновление в контроллере UsersController в Rails 4.0 будет по-прежнему называться update.
Запрос PUT по адресу /users/:id в Rails 4.0 будет, как и сегодня, маршрутизироваться к методу update. Т.о. если у вас есть API, которое производит вызовы PUT, оно по-прежнему будет работать.
Однако маршрутизация в Rails 4.0 также будет направлять на экшен update и PATCH-запросы к /users/:id. Т.е. и PUT и PATCH в Rails 4.0 будут маршрутизироваться к update.
Форма к сохраняемому ресурсу:
получит «patch» в скрытом поле «_method». Позволю себе заметить, что хак с «_method» — это просто способ обойти существующие ограничения браузеров. Как вы, вероятно, знаете, Rails вынуждена оперировать реальными методами HTTP, в т.ч. для обеспечения запросов PUT, DELETE, а теперь и PATCH.
Запросы PATCH доступны во всех местах, где в текущий момент применимы остальные HTTP-методы. DSL маршрутизации подвергнется расширению, в частности хэш :via теперь будет понимать символ :patch. Тесты также смогут обрабатывать PATCH-запросы. Подробности см. в оригинальном коммите.
Будет ли моё приложение понимать PATCH?
Да. Я лично проверил Apache, nginx, Phusion Passenger, Unicorn, Thin и WEBrick: они все понимают запросы PATCH. HTTP-клиенты также должны в целом справляться с PATCH-запросами. Вы можете попробовать выполнить в curl такой запрос:
Patch запрос что это
Что пишут в блогах
2 декабря выступала в Костроме у Exactpro Systems с темой «Организация обучения джуниоров внутри команды». Уже готово видео! Ссылка на ютуб — https://youtu.be/UR9qZZ6IWBA
Привет! В блоге появляется мало новостей, потому что все переехало в telegram.
Стоимость в цвете — 2500 рублей самовывозом (доставка еще 500-600 рублей, информация по ней будет чуть позже)
Онлайн-тренинги
Что пишут в блогах (EN)
Разделы портала
Про инструменты
Автор: Кристин Джеквони (Kristin Jackvony)
Перевод: Ольга Алифанова.
Как и PUT-запросы, PATCH-запросы меняют существующую запись, однако их куда сложнее тестировать! PUT-запрос меняет запись целиком, а PATCH – только одну часть запроса. С PATCH-запросом можно проводить множество различных операций – вы можете добавлять, заменять, удалять, копировать и перемещать значения в вашей записи. Опишу несколько примеров, а потом поговорим о том, как это тестировать.
Давайте рассмотрим простой пример записи, которую мы будем менять:
JSON-описание первой записи будет выглядеть примерно так:
Обратите внимание, что в первой записи отсутствует телефон. Проведем операцию добавления через PATCH-запрос, чтобы добавить номер.
URL для запроса будет примерно таким: https://app/customer/1, где 1 – это id пользователя, чьи данные мы изменяем, а HTTP-глагол для запроса будет, конечно, PATCH. Тело запроса будет выглядеть как-то так:
«op» в этом случае относится к операции, которую вы выполняете через PATCH. Мы используем операцию «add», добавление. «Path» показывает, к какому полю добавляется значение (в этом случае это поле номера телефона); «value» – это то значение, которое вы передаете в это поле, в этом случае – сам номер.
Когда эта операция завершена, JSON-описание будет выглядеть примерно так:
Вот как можно тестировать операцию добавления PATCH:
Теперь давайте рассмотрим операцию замены «replace«. Обратимся к записи номер 2, и заменим домашний телефон. Запись пока что выглядит вот так:
Эта операция заменит исходный номер телефона 8005551002 номером 8005551111, и запись будет выглядеть так:
Вот что можно попробовать сделать, тестируя PATCH-операцию «replace»:
Теперь давайте рассмотрим операцию удаления «remove». Начнем с этой записи:
Для удаления домашнего телефона этого пользователя мы снова воспользуемся URL: app/customer/1 и телом запроса, приведенным ниже:
Вот что мы получим в результате:
Операцию «remove» довольно легко тестировать. Нам нужно убедиться, что значение действительно удалено и заменено на null. Также неплохо удостовериться, что никакие иные значения не удалились по ошибке (к примеру, что не удалены оба телефона, а не только домашний). Также можно проверить, что обязательное поле невозможно удалить – мы должны получить соответствующее сообщение об ошибке.
Перейдем к операции перемещения «move». Давайте посмотрим на предыдущее состояние записи «Джон» и представим, что она неверна – его рабочий телефон на самом деле его домашний. Чтобы переместить телефон, используем вот такое тело запроса:
В этом примере «from» обозначает, где сейчас находится значение, а «path» – куда вы его перемещаете. После этой операции запись будет выглядеть так:
Ниже – идеи для тестирования операции «move»:
И, наконец, рассмотрим операцию копирования «copy». Она копирует существующее значение в другое место. Возьмем вот этот пример:
Если мы хотим скопировать домашний телефон в поле рабочего телефона, мы выполним следующий запрос:
Поле «from» показывает место, где находится значение, которое мы копируем, а «path» – куда его нужно скопировать. В результате запись будет выглядеть так:
Тестирование операции копирования очень похоже на тестирование операции перемещения:
Важно помнить, что PATCH-запросы могут выполняться цепочкой. К примеру, если мы начнем с этого сценария:
И отправим PATCH-запрос:
То результат будет таким:
Когда мы выполняем цепочку запросов PATCH, нужно протестировать, что любая невалидная операция приведет к невалидности запроса целиком. К примеру, если бы мы отправили такой запрос:
То мы получили бы сообщение об ошибке, и первая часть PATCH-запроса НЕ должна быть выполнена. Другими словами, домашний телефон все еще будет не пустым.
Как можно видеть, PATCH-запросы – это практически набор HTTP-глаголов! Их нужно использовать с особой осторожностью, потому что много чего может пойти не так. Если ваше приложение их использует, убедитесь, что вы протестировали их как по отдельности, так и в комбинации. Не забудьте протестировать и «счастливый путь», и способы, при которых нарушится валидация. Если база данных допускает «плохие» значения, не забудьте проверить патч поверх этих значений.
Больше информации по этой теме вы можете получить в курсе Тестирование REST API
Автоматизация Для Самых Маленьких. Заметки. RESTful API
Эта статья — одна из обещанных коротких заметок по ходу цикла статей Автоматизация Для Самых Маленьких.
Поскольку основным способом взаимодействия с IPAM-системой будет RESTful API, я решил рассказать о нём отдельно.
Воздаю хвалы архитекторам современного мира — у нас есть стандартизированные интерфейсы. Да их много — это минус, но они есть — это плюс.
Эти интерфейсы взаимодействия обрели имя API — Application Programming Interface.
Одним из таких интерфейсов является RESTful API, который и используется для работы с NetBox.
Если очень просто, то API даёт клиенту набор инструментов, через которые тот может управлять сервером. А клиентом может выступать по сути что угодно: веб-браузер, командная консоль, разработанное производителем приложение, или вообще любое другое приложение, у которого есть доступ к API.
Например, в случае NetBox, добавить новое устройство в него можно следующими способами: через веб-браузер, отправив curl’ом запрос в консоли, использовать Postman, обратиться к библиотеке requests в питоне, воспользоваться SDK pynetbox или перейти в Swagger.
Таким образом, один раз написав единый интерфейс, производитель навсегда освобождает себя от необходимости с каждым новым клиентом договариваться как его подключать (хотя, это самую малость лукавство).
Содержание
REST, RESTful, API
Ниже я дам очень упрощённое описание того, что такое REST.
Начнём с того, что RESTful API — это именно интерфейс взаимодействия, основанный на REST, в то время как сам REST (REpresentational State Transfer) — это набор ограничений, используемых для создания WEB-сервисов.
О каких именно ограничениях идёт речь, можно почитать в главе 5 диссертации Роя Филдинга Architectural Styles and the Design of Network-based Software Architectures. Мне же позвольте привести только три наиболее значимых (с моей точки зрения) из них:
А API, который предоставляют RESTful WEB-сервисы, называется RESTful API.
REST — не протокол, а, так называемый, стиль архитектуры (один из). Развиваемому вместе с HTTP Роем Филдингом, REST’у было предназначено использовать HTTP 1.1, в качестве транспорта.
Адрес назначения (или иным словом — объект, или ещё иным — эндпоинт) — это привычный нам URI.
Формат передаваемых данных — XML или JSON.
Для этой серии статей на linkmeup развёрнута read-only (для вас, дорогие, читатели) инсталляция NetBox: netbox.linkmeup.ru:45127.
На чтение права не требуются, но если хочется попробовать читать с токеном, то можно воспользоваться этим: API Token: 90a22967d0bc4bdcd8ca47ec490bbf0b0cb2d9c8.
Давайте интереса ради сделаем один запрос:
То есть утилитой curl мы делаем GET объекта по адресу netbox.linkmeup.ru:45127/api/dcim/devices/1/ с ответом в формате JSON и отступом в 4 пробела.
Или чуть более академически: GET возвращает типизированный объект devices, являющийся параметром объекта DCIM.
Этот запрос можете выполнить и вы — просто скопируйте себе в терминал.
URL, к которому мы обращаемся в запросе, называется Endpoint. В некотором смысле это конечный объект, с которым мы будем взаимодействовать.
Например, в случае netbox’а список всех endpoint’ов можно получить тут.
И ещё обратите внимание на знак / в конце URL — он обязателен.
Вот что мы получим в ответ:
Это JSON (как мы и просили), описывающий device с ID 1: как называется, с какой ролью, какой модели, где стоит итд.
Так будет выглядеть HTTP-запрос:
Так будет выглядеть ответ:
А теперь разберёмся, что же мы натворили.
Структура сообщений HTTP
HTTP-сообщение состоит из трёх частей, только первая из которых является обязательной.
Стартовая строка
Стартовые строки HTTP-запроса и ответа выглядят по-разному.
HTTP-Запрос
Метод определяет, какое действие клиент хочет совершить: получить данные, создать объект, обновить его, удалить.
URI — идентификатор ресурса, куда клиент обращается или иными словами путь к ресурсу/документу.
HTTP_VERSION — соответственно версия HTTP. На сегодняшний день для REST это всегда 1.1.
HTTP-Ответ
HTTP_VERSION — версия HTTP (1.1).
STATUS_CODE — три цифры кода состояния (200, 404, 502 итд)
REASON_PHRASE — Пояснение (OK, NOT FOUND, BAD GATEWAY итд)
Заголовки
В заголовках передаются параметры данной HTTP-транзакции.
Например, в примере выше в HTTP-запросе это были:
Тело HTTP-сообщения
Тело используется для передачи собственно данных.
В HTTP-ответе это может быть HTML-страничка, или в нашем случае JSON-объект.
Между заголовками и телом должна быть как минимум одна пустая строка.
При использовании метода GET в HTTP-запросе обычно никакого тела нет, потому что передавать нечего. Но тело есть в HTTP-ответе.
А вот например, при POST уже и в запросе будет тело. Давайте о методах и поговорим теперь.
Методы
Как вы уже поняли, для работы с WEB-сервисами HTTP использует методы. То же самое касается и RESTful API.
Возможные сценарии в реальной жизни описываются термином CRUD — Create, Read, Update, Delete.
Вот список наиболее популярных методов HTTP, реализующих CRUD:
Давайте на примере NetBox разберёмся с каждым из них.
HTTP GET
Это метод для получения информации.
Так, например, мы забираем список устройств:
Метод GET безопасный (safe), поскольку не меняет данные, а только запрашивает.
Он идемпотентный с той точки зрения, что один и тот же запрос всегда возвращает одинаковый результат (до тех пор, пока сами данные не поменялись).
На GET сервер возвращает сообщение с HTTP-кодом и телом ответа (response code и response body).
То есть если всё OK, то код ответа — 200 (OK).
Если URL не найден — 404 (NOT FOUND).
Если что-то не так с самим сервером или компонентами, это может быть 500 (SERVER ERROR) или 502 (BAD GATEWAY).
Все возможные коды ответов.
Тело возвращается в формате JSON или XML.
Давайте ещё пару примеров. Теперь мы запросим информацию по конкретному устройству по его имени.
Здесь, чтобы задать условия поиска в URI я ещё указал атритбут объекта (параметр name и его значение mlg-leaf-0). Как вы можете видеть, перед условием и после слэша идёт знак «?», а имя и значение разделяются знаком «=».
Так выглядит запрос.
Если нужно задать пару условий, то запрос будет выглядеть так:
Здесь мы запросили все устройства с ролью leaf, расположенные на сайте mlg.
То есть два условия отделяются друг от друга знаком «&».
Из любопытного и приятного — если через «&» задать два условия с одним именем, то между ними будет на самом деле не логическое «И», а логическое «ИЛИ».
То есть вот такой запрос и в самом деле вернёт два объекта: mlg-leaf-0 и mlg-spine-0
Попробуем обратиться к несуществующему URL.
HTTP POST
POST используется для создания нового объекта в наборе объектов. Или более сложным языком: для создания нового подчинённого ресурса.
Уточнение от arthuriantech:
Включая, но не ограничиваясь. Метод POST предназначен для передачи данных на сервер с целью дальнейшей обработки — он используется для любых действий, которые не нужно стандартизировать в рамках HTTP. До RFC 5789 он был единственным легальным способом вносить частичные изменения.
roy.gbiv.com/untangled/2009/it-is-okay-to-use-post
tools.ietf.org/html/rfc7231#section-4.3.3
То есть, если есть набор devices, то POST позволяет создать новый объект device внутри devices.
Выберем тот же Endpoint и с помощью POST создадим новое устройство.
Здесь уже появляется заголовок Authorization, содержащий токен, который авторизует запрос на запись, а после директивы -d расположен JSON с параметрами создаваемого устройства:
Запрос у вас не сработает, потому что Токен уже не валиден — не пытайтесь записать в NetBox.
В ответ приходит HTTP-ответ с кодом 201 (CREATED) и JSON’ом в теле сообщения, где сервер возвращает все параметры о созданном устройстве.
Теперь новым запросом с методом GET можно его увидеть в выдаче:
«q» в NetBox’е позволяет найти все объекты, содержащие в своём названии строку, идущую дальше.
POST, очевидно, не является ни безопасным, ни идемпотентным — он наверняка меняет данные, и дважды выполненный запрос приведёт или к созданию второго такого же объекта, или к ошибке.
HTTP PUT
Это метод для изменения существующего объекта. Endpoint для PUT выглядит иначе, чем для POST — в нём теперь содержится конкретный объект.
PUT может возвращать коды 201 или 200.
Важный момент с этим методом: нужно передавать все обязательные атрибуты, поскольку PUT замещает собой старый объект.
Поэтому, если например, просто попытаться добавить атрибут asset_tag нашему новому устройству, то получим ошибку:
Но если добавить недостающие поля, то всё сработает:
Обратите внимание на URL здесь — теперь он включает ID устройства, которое мы хотим менять (18).
HTTP PATCH
Этот метод используется для частичного изменения ресурса.
WAT? Спросите вы, а как же PUT?
PUT — изначально существовавший в стандарте метод, предполагающий полную замену изменяемого объекта. Соответственно в методе PUT, как я и писал выше, придётся указать даже те атрибуты объекта, которые не меняются.
А PATCH был добавлен позже и позволяет указать только те атрибуты, которые действительно меняются.
Здесь также в URL указан ID устройства, но для изменения только один атрибут serial.
HTTP DELETE
Очевидно, удаляет объект.
Метод DELETE идемпотентен с той точки зрения, что повторно выполненный запрос уже ничего не меняет в списке ресурсов (но вернёт код 404 (NOT FOUND).
Способы работы с RESTful API
Curl — это, конечно, очень удобно для доблестных воинов CLI, но есть инструменты получше.
Postman
Postman позволяет в графическом интерфейсе формировать запросы, выбирая методы, заголовки, тело, и отображает результат в удобочитаемом виде.
Кроме того запросы и URI можно сохранять и возвращаться к ним позже.
Так мы можем сделать GET:
Здесь указан Token в GET только для примера.
Postman служит только для работы с RESTful API.
Например, не пытайтесь через него отправить NETCONF XML, как это делал я на заре своей автоматизационной карьеры.
Один из приятных бонусов специфицированного API в том, что вы можете в Postman импортировать все эндпоинты и их методы как коллекцию.
Для этого в окне Import (File->Import) выберите Import From Link и вставьте в окно URL netbox.linkmeup.ru:45127/api/docs/?format=openapi.
Далее, всё, что только можно, вы найдёте в коллекциях.
Python+requests
Но даже через Postman вы, скорее всего, не будете управлять своими Production-системами. Наверняка, у вас будут внешние приложения, которые захотят без вашего участия взаимодействовать с ними.
Например, система генерации конфигурации захочет забрать список IP-интерфейсов из NetBox.
В Python есть чудесная библиотека requests, которая реализует работу через HTTP.
Пример запроса списка всех устройств:
Снова добавим новое устройство:
Python+NetBox SDK
В случае NetBox есть также Python SDK — Pynetbox, который представляет все Endpoint’ы NetBox в виде объекта и его атрибутов, делая за вас всю грязную работу по формированию URI и парсингу ответа, хотя и не бесплатно, конечно.
Например, сделаем то же, что и выше, использую pynetbox.
Список всех устройств:
Добавить новое устройство:
SWAGGER
За что ещё стоит поблагодарить ушедшее десятилетие, так это за спецификации API. Если вы перейдёте по этому пути, то попадёте в Swagger UI — документацию по API Netbox.
На этой странице перечислены все Endpoint’ы, методы работы с ними, возможные параметры и атрибуты и указано, какие из них обязательны. Кроме того описаны ожидаемые ответы.
На этой же странице можно выполнять интерактивные запросы, кликнув на Try it out.
По какой-от причине swagger в качестве Base URL берёт имя сервера без порта, поэтому функция Try it out не работает в моих примерах со Swagger’ом. Но вы можете попробовать это на собственной инсталляции.
При нажатии на Execute Swagger UI сформирует строку curl, с помощью которой можно аналогичный запрос сделать из командной строки.
В Swagger UI можно даже создать объект:
Для этого достаточно быть авторизованным пользователем, обладающим нужными правами.
То, что мы видим на этой странице — это Swagger UI — документация, сгенерированная на основе спецификации API.
С трендами на микросервисную архитектуру всё более важным становится иметь стандартизированный API для взаимодействия между компонентами, эндпоинты и методы которого легко определить как человеку, так и приложению, не роясь в исходном коде или PDF-документации.
Поэтому разработчики сегодня всё чаще следуют парадигме API First, когда сначала задумываются об API, а уже потом о реализации.
В этом дизайне сначала специфицируется API, а затем из него генерируются документация, клиентское приложение, серверная часть и необходимы тесты.
Swagger — это фреймворк и язык спецификации (который ныне переименован в OpenAPI 2.0), позволяющие реализовать эту задачу.
Углубляться в него я не буду.
За бо́льшими деталями сюда:
Критика REST и альтернативы
Существует и такая, да. Не всё в том мире 2000-го года так уже радужно.
Не являясь экспертом, не берусь предметно раскрывать вопрос, но дам ссылку на небесспорную статью на Хабре.
Альтернативным интерфейсом взаимодействия компонентов системы сегодня является gRPC. Ему же пророчат большое будущее на ниве новых подходов к работе с сетевым оборудованием. Но о нём мы поговорим когда-то в будущем, когда придёт его черёд.
Можно также взглянуть на многообещающий GraphQL, но нам опять же нет нужды с ним работать пока, поэтому остаётся на самостоятельное изучение.
Важно
Токен a9aae70d65c928a554f9a038b9d4703a1583594f был использован только в демонстрационных целях и больше не работает.
Прямое указание токенов в коде программы недопустимо и сделано здесь мной только в интересах упрощения примеров.