Предотвратить дубликаты в Rest API - PullRequest
0 голосов
/ 19 июня 2019

У нас есть конечная точка API, которая принимает людей.

Во время разговора мы проверяем, что PIN-код абонента еще не использовался, в этом случае мы отклоняем запрос с ошибкой ввода 422.

Недавно клиент пожаловался на дубликат PIN-кода, и мы обнаружили, что конечная точка API запускалась двумя разными вызовами REST с дублированными PIN-кодами, но без дублированного тела.

т.е.
{First Name: John, Last Name: Doe, PIN: 722}
{First Name: Jane, Last Name: Doe, PIN: 722}

Поскольку оба приходят в течение миллисекунд друг от друга, когда проверка выполняется для второй записи для дубликата ПИН-кода, он возвращает значение false, поскольку первая запись еще не была вставлена ​​в БД, и в результате продолжает обрабатывать вторую запись. .

Мы рассмотрели несколько вариантов, таких как уникальные ограничения для БД, которые работают, но потребуют огромного количества переделок, чтобы вывести ошибку до ответа REST API. Огромный риск на процветающем производстве APP.

Существует около 5-6 различных вызовов API, которые могут модифицировать коллекцию PIN в том или ином виде, и около 20-30 различных API, где существует такая проблема (уникальные электронные письма, уникальное имя элемента и т. Д.), Поэтому я не уверен мы можем поддерживать списки для быстрого доступа.

Помимо ограничений БД, есть ли другие доступные нам опции, которые было бы проще реализовать? Возможно, какой-то неясный атрибут в классе .NET APIController.

По крайней мере, мне хотелось бы, чтобы запрос был сделан, а последующие запросы были поставлены в очередь. Я знаю, что мы можем просто сохранить полезную нагрузку для последующей обработки, однако, исходя из того, что API уже используются, это, похоже, не вариант, когда очередь должна блокировать ответ.

Попытка поиска в Google была далека от успеха, поскольку все предполагают, что я пытаюсь отклонить дубликаты полных тел.

1 Ответ

0 голосов
/ 19 июня 2019

Если вы основываете проверку на том, существует ли PIN-код в БД, теоретически вы можете иметь десятки или сотни потенциальных дубликатов, поступающих в REST API, все при условии, что PIN-код в порядке, так как база данных говорит медленно существует ли PIN-код.

Если вы думаете об этом как о конвейере:

клиент -> API -> проверка PIN-кода из db -> ok -> вставить в db

PIN check from db является узким местом, поскольку оно, скорее всего, будет медленнее, чем входящие вызовы REST. Как вы говорите, решение состоит в том, чтобы обеспечить уникальность на уровне базы данных, но если это не практично, вы можете вместо этого использовать проверку «шлюз». Как правило, кэш ПИН-кода, который быстро обновляется / запрашивается, и ПИН-коды добавляются в него после того, как запрос был принят для обработки и до его записи в базу данных. Таким образом, конвейер становится:

клиент -> API -> проверка PIN из кеша -> ок -> запись PIN в кеш -> вставить в дБ

и второй запрос будет иметь вид:

клиент -> API -> проверка PIN-кода из кэша -> существует -> ошибка

, поэтому кэш не отстает от запросов, что позволяет более неторопливым операциям с базой данных продолжать работу с известными чистыми данными. Вам придется создавать кэш (из ПИН-кодов в базе данных) при каждом перезапуске службы и разрешать вызовы API только после того, как кэш будет готов, если это кэш-память. Или вы можете использовать дисковый кеш. Недостатком является то, что он дублирует все PIN-коды в вашей базе данных, но это компромисс, который позволяет вам не отставать от проверки PIN-кодов в вызовах API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...