Что такое идемпотентность http методов и почему она важна

идемпотентность, идемпотентность http, идемпотентность запроса, идемпотентность http запросов, идемпотентность методов, ключ идемпотентности, идемпотентность пример, идемпотентность методов http

Что такое идемпотентность?

Идемпотентность — это свойство операции, при котором её повторное применение к ресурсу не приводит к изменению его состояния. Другими словами, если вы выполняете идемпотентную операцию несколько раз, состояние ресурса будет таким же, как при однократном выполнении. В противном случае операция является не идемпотентной.

Идемпотентность HTTP запросов — это свойство определенных HTTP методов, при котором повторное выполнение одного и того же запроса с теми же параметрами не изменяет состояние ресурса на сервере. Другими словами, идемпотентные запросы можно выполнять несколько раз, а результат будет как при однократном запросе.

Идемпотентность обеспечивает надежность и предсказуемость взаимодействия между клиентами и серверами. Она гарантирует, что повторные запросы не вызовут неожиданных или нежелательных изменений на сервере. Это важно в критических системах, например банковские приложения, где дублирование операций может иметь серьезные последствия. В сетевых условиях могут возникать сбои, и запросы могут быть потеряны или задублированы. Также, в случае сбоя, запросы могут выполняться в непредсказуемом порядке. Идемпотентные операции позволяют клиентам безопасно повторять запросы, не беспокоясь о возможных проблемах в сети. В идемпотентных операциях сервер может использовать кэширование без опасения, что это повлияет на конечный результат. Это способствует улучшению производительности и отзывчивости системы. Идемпотентные операции позволяют серверам игнорировать повторяющиеся запросы, что может снизить нагрузку на серверы и сеть.

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

Идемпотентные HTTP запросы

В RESTful идемпотентными являются HTTP методы GET, PUT, DELETE, потому что повторный вызов любого из этих запросов с теми же данными и URI приведет к тому же состоянию ресурса, что и при первом запросе.

Пример запроса Состояние ресурса до первого вызова запроса Состояние ресурса после первого вызова запроса Состояние ресурса после повторного вызова запроса
GET v1/users { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Петр”, “age”:32 } { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Петр”, “age”:32 } { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Петр”, “age”:32 }
PUT v1/user/1
BODY:
{ “lastname”: “Иванов”, “firstname” : “Иван”, “age”:33 }
{ “id”:”1”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:32 } { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:33 } { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:33 }
DELETE v1/user/1 { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:33 } Ресурс пользователь с идентификатором – 1 не существует Ресурс пользователь с идентификатором – 1 не существует

Не идемпотентные HTTP запросы

К не идемпотентным запросам в RESTful относятся POST и PATCH, т.к. повторный вызов идентичных запросов может привести к изменению состояния ресурса. Применительно к POST запросу может быть создан дубль ресурса. Повторный вызов идентичного PATCH запроса может привести к изменению состояния ресурса.

Рассмотрим пример не идемпотентного PATCH запроса. Предположим, нам необходимо с помощью PATCH запроса реализовать увеличение возраста пользователя на указанную величину. Существует ресурс пользователь { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Петр”, “age”:32 } .  Получив от клиента запрос PATCH v1/user/1 с телом { “id”:”1”, “ageIncrement”: 3 } сервер изменит состояние ресурса на пользователь на { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Петр”, “age”:35 }, т.е увеличит значение атрибута age на значение ageIncrement. Каждый последующий вызов идентичного запроса будет увеличивать значение age на значение ageIncrement, т.е после повторного вызова идентичного запроса состояние ресурса на пользователь будет { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Петр”, “age”:38 }.

Пример запроса Состояние ресурса до первого вызова запроса Состояние ресурса после первого вызова запроса Состояние ресурса после повторного вызова запроса
POST v1/users
BODY:
{ “lastname”: “Иванов”, “firstname” : “Иван”, “age”:32 }
{ “id”:”1”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:32 } { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:32 },
{ “id”:”2”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:32 }
PATCH v1/user/1
BODY:
{ “id”:”1”, “ageIncrement”: 3 }
{ “id”:”1”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:32 } { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:35 } { “id”:”1”, “lastname”: “Иванов”, “firstname” : “Иван”, “age”:38 }

Повторный вызов POST и PATCH запросов может привести к изменению состояния ресурса. Но POST и PATCH можно сделать идемпотентными, достаточно передать вместе с запросом ключ идемпотентности.

Ключ идемпотентности (Idempotency-Key)

Idempotency-Key — это уникальный идентификатор, который помогает серверу отслеживать идемпотентность запросов. Клиенты включают Idempotency-Key в запросы, чтобы сервер мог определить, что запрос уже обработан. Если сервер обнаруживает Idempotency-Key вновь, он может игнорировать дублирующий запрос и вернуть тот же результат, что и в первый раз.

Пример использования ключа идемпотентности

Вы системный аналитик на проекте мобильное приложение для заказа доставки еды. Одной из функций является «Мультизаказ», т.е. можно сделать новый заказ, пока существующий еще не доставлен. В процессе эксплуатации приложения некоторые пользователи начали жаловаться, что им доставляют по 2 идентичных заказа. Разбор кейсов показал, что сервер при получении двух идентичных POST запросов просто создавал новый заказ.

Пример POST запроса на создание заказа

POST https://someurl/api/v1/order
BODY: { «item»: «Название блюда», «count»: 1 }

При повторном получении этого запроса сервер создаст еще один заказ. Но если мы будем передавать в запросе Idempotency-Key, то сервер получив запрос проверит значение Idempotency-Key. Если заказ с таким Idempotency-Key уже был создан ранее, то сервер просто вернет статус заказа.

Пример идемпотентного POST запроса на создание заказа

POST https://someurl/api/v1/order
Idempotency-Key: c2913fr3-de4r-4er6-5tr6-rt5ttg5re0fa

BODY: { «item»: «Название блюда», «count»: 1 }

Техноблог
Добавить комментарий