#design-patterns #architecture #event-handling #microservices #domain-driven-design
#шаблоны проектирования #архитектура #обработка событий #микросервисы #дизайн, управляемый доменом
Вопрос:
Я хочу создать систему для управления проектами с помощью задачи / проблемы / чата. Это не что-то коммерческое, просто для учебных целей. Это упрощенное описание, содержащее только то, что необходимо для представления проблемы.
Первая проблема, с которой я столкнулся, заключалась в том, как добавить задачу с помощью службы задач, не запрашивая службу проекта каждый раз, если пользователь является участником данного проекта. Я знаю, что чем больше сообщений beetwen services == больше проблем, больше задержек и, как правило, AvoidBadTM. Поэтому я решил использовать JWT для каждого микросервиса. Пользователь, который хочет добавить задачу с помощью службы задач, должен сначала запросить службу аутентификации: дайте мне jwt для разрешений Task, ProjectX и include. Auth вызовет службу проекта, чтобы проверить, является ли пользователь участником, и сгенерирует правильный токен JWT. У нас все еще есть службы обмена сообщениями, но это один вызов для периода жизни токена, а не для каждого вызова службы задач. Здесь возникает проблема.
Что делать, если пользователь удален / запрещен из проекта или проект был удален? Если служба задач не заботится о проектах — ей важно только, действителен ли JWT, чтобы пользователь мог создать задачу X для идентификатора проекта Y, тогда как предотвратить доступ запрещенного (из проекта) пользователя к этой службе? Кроме того, если проект удален, а служба проекта отправляет событие на шину событий «Я удалил проект X», служба задач считывает это событие и удаляет все задачи, назначенные проекту X. Но что делать, когда у какого-то пользователя все еще есть действительный токен доступа, и он создает другую задачу после обработки события? Служба задач не проверяет, существует ли проект, и в результате мы получаем зависшую задачу в базе данных.
Моим решением этой проблемы было бы хранить в базе данных службы задач информацию о существующих проектах. Только идентификаторы, поэтому объем памяти / хранилища минимален. Поэтому, когда служба проекта выдает «Событие удаления проекта», служба задач не только очищает все задачи с заданным идентификатором проекта, но и удаляет сохраненный идентификатор проекта, поэтому создание задачи невозможно. Это хороший подход? А как насчет запрещенных пользователей? Еще одна запись в базе данных и событие для подписки?
Комментарии:
1. Идентификаторы проектов в службе задач кажутся мне хорошими. Он следует принципам агрегированных отношений DDD. Для запрещенного пользователя почему бы не использовать аналогичную технику, отслеживая активных пользователей в службе задач / проектов. Просто переименуйте пользователя с более подходящим именем, например, project manager, чтобы соответствовать правилу ограниченного контекста DDD.
Ответ №1:
Моим решением этой проблемы было бы хранить в базе данных службы задач информацию о существующих проектах. Только идентификаторы, поэтому объем памяти / хранилища минимален. Поэтому, когда служба проекта выдает «Событие удаления проекта», служба задач не только очищает все задачи с заданным идентификатором проекта, но и удаляет сохраненный идентификатор проекта, поэтому создание задачи невозможно. Это хороший подход?
Безусловно, задача должна знать, к какому проекту она принадлежит, поэтому я не вижу в этом ничего плохого — это имеет смысл.
А как насчет запрещенных пользователей? Еще одна запись в базе данных и событие для подписки?
Вы упомянули, что «Auth вызовет службу проекта, чтобы проверить, является ли пользователь участником, и сгенерирует надлежащий токен JWT», поэтому результатом должно быть то, что служба проекта должна сказать, что пользователь не является участником проекта. Теперь в вашей системе у вас, вероятно, будет users
служба, у которой будет API для запрета пользователя. Я считаю, что должно произойти следующее:
- В
projects
сервисе у вас есть вызываемая таблицаmembers
, которая имеетN to N
связь между auser_id
иproject_id
- Когда администратор (не уверен, как процесс запрета будет работать в вашей системе) хочет запретить пользователю, он вызывает API в
users
service users
служба выдаст событие, в котором говорится, чтоuser 1 was banned
projects
служба прослушает это событие и удалит записи об этомuser_id
изmembers
таблицы