Я разрабатываю веб-службу RESTful с использованием ROA (архитектура, ориентированная на ресурсы).
Я пытаюсь разработать эффективный способ гарантировать идемпотентность для запросов PUT, которые создают новые ресурсы в случаях, когда сервер назначает ключ ресурса.
Насколько я понимаю, традиционный подход заключается в создании типа ресурса транзакции, такого как /CREATE_PERSON. Взаимодействие клиент-сервер для создания нового личного ресурса будет состоять из двух частей:
Шаг 1. Получите уникальный идентификатор транзакции для создания нового ресурса PERSON:::
**Client request:**
POST /CREATE_PERSON
**Server response:**
200 OK
transaction-id:"as8yfasiob"
Шаг 2. Создайте новый ресурс пользователя в запросе, который гарантированно будет уникальным, используя идентификатор транзакции:::
**Client request**
PUT /CREATE_PERSON/{transaction_id}
first_name="Big bubba"
**Server response**
201 Created // (If the request is a duplicate, it would send this
PersonKey="398u4nsdf" // same response without creating a new resource. It
// would perhaps send an error response if the was used
// on a transaction id non-duplicate request, but I have
// control over the client, so I can guarantee that this
// won't happen)
Проблема, которую я вижу с этим подходом, заключается в том, что он требует отправки двух запросов на сервер, чтобы выполнить одну операцию создания нового ресурса PERSON. Это создает проблемы с производительностью, увеличивая вероятность того, что пользователь будет ждать, пока клиент выполнит свой запрос.
Я пытался обдумать идеи по устранению первого шага, такого как предварительная отправка идентификатора транзакции с каждым запросом, но большинство моих идей имеют другие проблемы или связаны с отказом от сохранения состояния приложения.
Есть ли способ сделать это?
Редактировать::::::
Решение, к которому мы пришли, заключалось в том, чтобы клиент получал UUID и отправлял его вместе с запросом. UUID — это очень большое число, занимающее пространство в 16 байт (2^128). Вопреки тому, что может интуитивно подумать человек с программным складом ума, принято генерировать UUID случайным образом и предполагать, что это уникальное значение. Это связано с тем, что количество возможных значений настолько велико, что вероятность случайного генерирования двух одинаковых чисел достаточно мала, чтобы быть практически невозможной.
Одно предостережение заключается в том, что наши клиенты запрашивают UUID с сервера (GET uuid/
). Это связано с тем, что мы не можем гарантировать среду, в которой работает наш клиент. Если возникла проблема, например, с заполнением генератора случайных чисел на клиенте, то вполне мог возникнуть конфликт UUID.