nest js обмен сообщениями на основе событий с 1 производителем и 2 потребителями - PullRequest
1 голос
/ 21 июня 2020

С помощью микросервисов nest js вы можете отправлять сообщения и получать результат, используя подход на основе запросов / ответов. Это реализуется комбинацией @MessagePattern и client.send('my_pattern', myData). Для примера см. Вложенные документы: https://docs.nestjs.com/microservices/basics#request -response и https://docs.nestjs.com/microservices/basics#sending -messages .

Как мне получить результат в подходе, основанном на событиях ?

Предположим, у вас есть микросервис пользователя и микросервис аутентификации. Каждый раз, когда создается пользователь, вы хотите, чтобы также создавалась тема auth (сохраняя имя пользователя и ha sh пароля, чтобы пользователь мог войти в систему с запросом api к микросервису auth вместо пользовательского сервиса).

auth / auth.controller.ts

  @EventPattern('EVT_USER_CREATED')
  public async handleUserCreated(data: any): Promise<AuthSubject> {
    if (!data.username || !data.password) {
      throw new RpcException('Auth subject must supply username and password');
    } 
    const newSubject: CreateAuthSubject = {
      username: data.username,
      password: data.password,
      email: data.email ?? '',
    };
    const sub = await this.subjectService.create(subject);
    return sub;
  }

user / user.controller.ts

  @Post('')
  @ApiBody({ type: CreateUser })
  @ApiCreatedResponse({ type: User })
  public async create(@Body() user: CreateUser): Promise<User> {
    const newUser = await this.userService.create(user);

    this.userQueue
      .emit<any, CreateUser>('EVT_USER_CREATED', user)
      .subscribe((res) => {
        console.log(res);   // undefined
      });

    return newUser;
  }

Чтобы убедиться, что в моей настройке нет ошибок, я изменил @EventPattern на @MessagePattern и this.userQueue.emit<... на this.userQueue.send<.... Это сработало, т.е. res был допустимым субъектом аутентификации с именем пользователя и паролем, как и ожидалось. Однако с подходом, основанным на событиях, описанном в этом вопросе, res всегда undefined (независимо от того, возвращает или нет контроллеры аутентификации handleUserCreated).

В конечном итоге я бы хотелось бы добиться следующего: если другой микросервис должен обрабатывать события 'EVT_USER_CREATED', я просто добавляю метод @EventPattern('EVT_USER_CREATED') public async handleUserCreated к его контроллеру. Наблюдаемый this.userQueue.emit<any, CreateUser>('EVT_USER_CREATED', user) затем получит оба результата: Один раз для каждой микрослужбы, потребляющей событие, созданное пользователем.

Итак, предположим, я добавляю третью микросервис: микросервис клиента, который отвечает за сохранение платежной информации, историю заказов, эт c. Как и служба аутентификации, он подписывается на 'EVT_USER_CREATED'.

customer / customer.controller.ts

  @EventPattern('EVT_USER_CREATED')
  public async handleUserCreated(data: any): Promise<AuthSubject> {    
    const customer = await this.customerService.create(data);
    return customer ;
  }

Теперь, после вышеуказанной настройки, авторизация микросервисов и клиент будут альтернативный прием событий: если пользовательские микросервисы генерируют создание пользователя, только служба аутентификации отреагирует на это и создаст тему аутентификации от пользователя шляпы. Для этого пользователя не будет создано ни одного клиента. Для следующего пользователя, созданного в пользовательском микросервисе, будет создан только клиент, но не субъект авторизации. Третий созданный пользователь снова будет использоваться микросервисом auth, но не микросервисом клиента. И так далее.

                                           -- auth microservice 
                                         /
user microservice --- message broker ---
                                         \
                                           -- customer microservice

Подводя итог: как мне получить архитектуру обмена сообщениями, показанную на диаграмме, так что мне нужен только один вызов emit(...) в user.controller.ts и, чтобы я обнаружил оба ответы в подписке на emit(...) звонок?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...