Я строю на основе предыдущее обсуждение, которое я провел с Джоном Скитом.
Суть моего сценария такова:
- Клиентское приложение имеет возможность создавать новые объекты PlaylistItem, которые необходимо сохранить в базе данных.
- Вариант использования требует, чтобы PlaylistItem был создан таким образом, чтобы клиенту не приходилось ждать ответа от сервера перед отображением PlaylistItem.
- Клиент генерирует UUID для PlaylistItem, показывает PlaylistItem в клиенте, а затем выдает команду сохранения на сервер.
На данный момент я понимаю, что было бы плохой практикой использовать UUID, сгенерированный клиентом, в качестве PK объекта в моей базе данных. Причина этого в том, что злоумышленник может изменить сгенерированный UUID и вызвать конфликты PK в моей БД.
Чтобы уменьшить любые убытки, которые могут возникнуть в результате принудительного столкновения PK в PlaylistItem, я решил определить PK как составную часть двух идентификаторов - UUID, созданного клиентом, и GUID, созданного сервером. Созданный сервером GUID - это идентификатор списка воспроизведения PlaylistItem.
Я использую это решение некоторое время, но я не понимаю, почему / считаю, что мое решение лучше, чем просто доверять идентификатору клиента. Если пользователь может вызвать столкновение PK с объектами PlaylistItem другого пользователя, я думаю, я должен предположить, что они также могут предоставить PlaylistId этого пользователя. Они все еще могли вызывать столкновения.
Так что да. Как правильно делать что-то подобное? Разрешить клиенту создать UUID, сервер показывает палец вверх / вниз при успешном сохранении. Если обнаружена коллизия, отменить изменения клиента и уведомить об обнаруженной коллизии?