Впервые я думаю об этом ...Должен ли возвращаться натуральный или суррогатный ключ в API?
До сих пор я всегда использовал естественный ключ в своем API. Например, REST API, позволяющий обрабатывать объекты, URL-адрес будет выглядеть как /entities/{id}
, где id является естественным ключом, известным пользователю (идентификатор передается запросу POST, который создает объект). После создания сущности пользователь может использовать несколько команд (GET, DELETE, PUT ...) для управления объектом. Сущность также имеет суррогатный ключ, созданный базой данных.
Теперь подумайте о следующей последовательности:
- Пользователь создает объект с идентификатором 1. (
POST /entities
с телом, содержащим ид 1) - Другой пользователь удаляет объект (
DELETE /entities/1
) - То же самое другой пользователь снова создает объект (
POST /entities
с телом, содержащим идентификатор 1) - Первый пользователь принимает решение об изменении лица (
PUT /entities/1
с кузовом)
Прежде чем выполнить шаг 4, в базе данных все еще есть объект с идентификатором 1, но это не тот же объект, созданный во время шага 1. Проблема заключается в том, что на этапе 4 определяется, что сущность модифицируется на основе естественного ключа что одинаково для удаленной и новой сущности (в то время как суррогатный ключ отличается). Поэтому шаг 4 будет успешным, и пользователь никогда не узнает, что он работает над новым объектом.
Я вообще также использую оптимистичную блокировку в своих приложениях, но я не думаю, что это помогает здесь. После шага 1 поле версии сущности равно 0. После шага 3 поле версии нового объекта также равно 0. Поэтому проверка версии не поможет. Правильно ли использовать поле метки времени для оптимистической блокировки?
Является ли "хорошим" решением для возврата суррогатного ключа пользователю? Таким образом, пользователь всегда предоставляет суррогатный ключ серверу, который может использовать его для обеспечения того, чтобы он работал на одном и том же объекте, а не на новом?
Какой подход вы рекомендуете?
Спасибо, Микаэль
Для заинтересованных пользователей посмотрите на чат с Gaz_Edge (ссылку на чат можно найти в последнем комментарии принятого ответа). –