Запрос состояния асинхронной операции в архитектуре микросервиса - PullRequest
1 голос
/ 20 сентября 2019

Мы находимся в процессе редизайна нескольких наших конечных точек API REST для перехода на архитектуру микросервиса.

Здесь мы работаем над конечной точкой /invitations/:id/confirm.

Эта конечная точка создает User, Account, используя предоставленные Invitation.

У нас есть 3 агрегата Invitation, User и Account.

Номинальный поток, которым мы являемся в настоящее время , следующий:

  • Проверьте, существует ли Invitation
  • Убедитесь, что приглашение может быть подтверждено
  • Создать User
  • Создать Account
  • Удалить Invitation
  • Возврат UserId

Эта операциясделано в процессе, который объяснил, почему мы можем вернуть UserId сразу.Мы просто загружаем наши агрегаты из базы данных, выполняем соответствующую бизнес-логику и сохраняем результат.

Для внедрения микроуслуг потребуется асинхронная обработка.Другими словами, мы должны отправить команду на шину и вернуть код состояния 202.

В нашем плане мы хотим запустить команду с именем RequestInvitationConfirmation.Базовая проверка будет происходить при создании этой команды.

Затем эта команда будет отправлена ​​через шину потребителю, который отвечает за: - загрузку агрегатов приглашений (убедитесь, что они существуют) - вызов методов RequestConfirmation (проверит, что приглашение может быть подтверждено) - повышениесобытие InvitationConfirmationRequested

Событие InvitationConfirmationRequested инициирует SAGA, отвечающую за организацию связи между службами

  • OnInvitationConfirmationRequested
    • Отправка CreateUserкоманда
  • OnUserCreated
    • Отправить CreateAccount команда
  • OnAccountCreated
    • Отправить DeleteInvitation команда
  • OnInvitationDeleted
    • Повышение InvitationConfirmed

Поскольку оно асинхронное, мы должны предоставитьспособ получить текущее рабочее состояние.Я видел (https://www.adayinthelifeof.nl/2011/06/02/asynchronous-operations-in-rest/, https://asyncrestapi.docs.apiary.io/#), что общий подход состоит в том, чтобы предложить конечные точки /queue/:id ИЛИ /actions/:id.

Вот где мы запутались. Как вы можете предложитьодна конечная точка, когда состояния могут полностью отличаться от SAGA к другому?

Thx

1 Ответ

0 голосов
/ 20 сентября 2019

Чтобы ваша сага обрабатывала сообщения в рамках одного потока, вы должны соотнести все ваши сообщения с соответствующим экземпляром.Когда сага запускается первым сообщением, идентичность саги генерируется в соответствии с правилами:

Event(() => ItemAdded, x => x.CorrelateBy(cart => cart.UserName, context => context.Message.UserName)
    .SelectId(context => Guid.NewGuid()));

Таким образом, этот идентификатор будет использоваться как идентификатор вашей саги, который сохраняется в хранилище саги.

class ShoppingCart :
    SagaStateMachineInstance
{
    public Guid CorrelationId { get; set; }
    public string CurrentState { get; set; }

Здесь CorrelationId является идентификатором саги, следовательно, является идентификатором корреляции всего процесса.

Если у вас есть доступ к хранилищу саги (и у вас есть),довольно просто предоставить конечную точку HTTP API для получения текущего состояния саги, посмотрев на значение свойства CurrentState в вашем состоянии саги в базе данных, которую вы используете для сохранения саг.

...