Следует ли использовать первичные ключи базы данных для идентификации сущностей в микросервисах?
Учитывая, что у меня есть два микросервиса: Service A и Service B.
Сервис A владеет полными данными о клиентах, а сервис B требует небольшого подмножества этих данных (которые он получает от сервиса A, скажем, посредством некоторой массовой загрузки).
Обе службы хранят клиентов в своей собственной базе данных.
Если служба B затем должна взаимодействовать со службой A, скажем, для получения дополнительных данных (например, GET / customers / {id}), ей явно нужен уникальный идентификатор, который совместно используется двумя службами.
Поскольку идентификаторы являются идентификаторами GUID, я мог бы просто использовать PK из службы A при создании записи в службе B. Таким образом, оба PK совпадают.
Однако это звучит крайне хрупко. Один из вариантов - сохранить «внешний идентификатор» (или «идентификатор источника») в качестве отдельного поля в службе B и использовать его для взаимодействия со службой A. И, вероятно, это строка, поскольку однажды она может не быть GUID.
Есть ли в этом «лучшая практика»?
Обновить
Итак, я провел еще несколько исследований и нашел несколько связанных обсуждений:
Следует ли предоставлять первичный ключ в URL-адресах REST API?
Является ли плохой практикой предоставлять клиенту идентификатор базы данных в вашем REST API?
Слизни как первичные ключи
заключение
Я думаю, что моя идея попытаться сохранить оба первичных ключа для клиента одинаковыми в сервисах A и B была ошибочной. Это потому что:
- Очевидно, что PK зависят от конкретной реализации службы, поэтому они могут быть полностью несовместимы, например, UUID и автоматически увеличивающийся INT.
- Даже если вы можете гарантировать совместимость, несмотря на то, что оба объекта называются «Клиент», они фактически представляют собой две (потенциально очень разные) концепции, и обе службы А и Б «владеют» своей собственной записью «Заказчик». Что вы можете сделать, это синхронизировать некоторые данные клиентов в этих службах.
Итак, теперь я думаю, что любая служба может предоставлять данные о клиентах через свой собственный уникальный идентификатор (в моем случае это PK GUID), и если одной службе необходимо получить дополнительные данные о клиентах из другой службы, она должна сохранить идентификатор / ключ другой службы и использовать его. Итак, по сути, вернемся к моей идее «внешний идентификатор» или «идентификатор источника», но, возможно, более конкретный, как «идентификатор службы B».
Ответы
Я думаю, это немного зависит от источника данных и вашего дизайна. Но одна вещь, которую я бы избегал делиться, - это первичный ключ, который представляет собой GUID или целое число с автоинкрементом для внешней службы. Это внутренние детали вашей службы, а не то, от чего должны зависеть другие службы.
Я бы предпочел иметь внешний идентификатор, который лучше понимают другие службы и, возможно, бизнес в целом. Это может быть уникальный номер клиента, номер заказа или номер полиса, а не домен id
. Вы также можете рассматривать их как «идентификатор бизнеса». Также следует иметь в виду, что внешний идентификатор также может быть предоставлен конечному пользователю. Следовательно, это повсеместный способ идентификации этой «сущности» во всей организации и службах, независимо от того, используете ли вы дизайн, управляемый событиями, или ваши службы взаимодействуют через API. Я бы предоставил только идентификаторы БД инфраструктуре или репозиторию. Кроме того, это только бизнес / внешний идентификатор.
Что ж, если у вас есть представление о Value Object, бизнес-идентификатор будет намного лучше для разработки.
DDD ориентирован на бизнес, чистый UUID / Auto increment ID не может его представить.
Используйте идентификатор бизнес-значения (UL ID), например идентификатор клиента, вместо простого идентификатора.