NestJS: представить содержимое ответа с URL-адреса при проверке работоспособности

#nestjs #health-check

Вопрос:

Я пытаюсь разработать конечную точку проверки работоспособности с помощью NestJS (в которой у меня нет опыта). Одна из зависимостей, которую я хочу проверить, — это служба SMS Twilio. До сих пор лучшим URL-адресом, который я нашел для сбора этой информации, был https://status.twilio.com/api/v2/status.json. Проблема здесь в том, что я хочу не просто пропинговать этот адрес, а собрать его ответ JSON и представить некоторую информацию, которую он предоставляет, а именно::

Ответ JSON на странице состояния Twilio

Возможно ли это, используя (или нет) модуль Terminus? В официальных документах я ничего не нашел по этому поводу, только более простые примеры с использованием pingCheck / responseCheck : https://docs.nestjs.com/recipes/terminus

Комментарии:

1.Почему бы не создать обычную controller /status/twillio конечную точку вместо конечной точки?

2. В этом ты прав, я об этом не подумал. Однако одной из причин может быть то, что эта проверка работоспособности также проверяет другую зависимость-доступность экземпляра Mongo ( async () => this.db.pingCheck('database') ). В идеале эта конечная точка должна представлять агрегированную информацию из этих 2 зависимостей.

Ответ №1:

Да, это возможно.

Я никогда не использовал это, но HttpHealthIndicator responseCheck метод проверки зависит от ответного сообщения API. Вы можете указать функцию обратного вызова для анализа ответов из API. Функция обратного вызова должна возвращать логическое значение, представляющее статус API.

Я не смог найти это в документах, но вы можете увидеть это здесь.

Комментарии:

1. Спасибо, как упоминалось в первоначальном вопросе, я уже посмотрел responseCheck и не нашел, как достичь того, что я ищу, но я попробую еще раз. В любом случае, проблема здесь в том, что я не пытаюсь анализировать ответ, я пытаюсь отобразить его часть (подчеркнуто красным на изображении выше).

2. О, прости. Я неправильно понял и пропустил ваш комментарий по поводу responseCheck . Если вы хотите создать что-то вроде прокси-сервера для отображения исходной полезной нагрузки API, я думаю, что самый простой способ-создать обычный контроллер и маршрут.

Ответ №2:

Хотя в то же время логика этой проверки работоспособности изменилась (и поэтому этот вопрос устарел), это было временное решение, которое я нашел до того, как это произошло (в основном обычная конечная точка с использованием axios, как указано в одном из комментариев выше).:

Контроллер

     import { Controller, Get } from '@nestjs/common';
    import { TwilioStatusService } from './twilio-status.service';
    
    @Controller('status')
    export class TwilioStatusController {
      constructor(private readonly twilioStatusService: TwilioStatusService) {}
    
      @Get('twilio')
      getTwilioStatus() {
        const res = this.twilioStatusService.getTwilioStatus();
        return res;
      }
    }
 

Обслуживание

     import { HttpService } from '@nestjs/axios';
    import { Injectable } from '@nestjs/common';
    import { map } from 'rxjs/operators';
    
    @Injectable()
    export class TwilioStatusService {
      constructor(private httpService: HttpService) {}
    
      getTwilioStatus() {
        return this.httpService
          .get('https://status.twilio.com/api/v2/status.json')
          .pipe(map((response) => response.data.status));
      }
    }
 

Конечно, это не было оптимальным решением, так как я должен был сделать эту конечную точку отдельную для проверки доступности MongoDB (обычная проверка работоспособности NestJS с использованием Terminus), целью которой была проверка работоспособности, которая склеивала обе конечные точки вместе.

Ответ №3:

Возможно слияние в любом свойстве с полученным объектом. Вы можете увидеть это в интерфейсе машинописи

 /**
 * The result object of a health indicator
 * @publicApi
 */
export declare type HealthIndicatorResult = {
    /**
     * The key of the health indicator which should be uniqe
     */
    [key: string]: {
        /**
         * The status if the given health indicator was successful or not
         */
        status: HealthIndicatorStatus;
        /**
         * Optional settings of the health indicator result
         */
        [optionalKeys: string]: any;
    };
};
 

И вот пример:

diagnostics/health/healthcheck.controller
 import { Controller, Get } from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger'
import { HttpService } from '@nestjs/axios'
import { HealthCheckService, HealthCheck, HealthIndicatorStatus, HealthCheckError } from '@nestjs/terminus'

@ApiTags('diagnostics')
@Controller('diagnostics/health')
export class HealthController {
  constructor(
    private health: HealthCheckService,
    private httpService: HttpService,
  ) { }

  @Get()
  @HealthCheck()
  check() {
    return this.health.check([

      () => this.httpService.get('http://localhost:9002/api/v1/diagnostics/health').toPromise().then(({ statusText, config: { url }, data }) => {
        const status: HealthIndicatorStatus = statusText === 'OK' ? 'up' : 'down'
        return { 'other-service': { status, url, data } }
      }).catch(({ code, config: { url } }) => {
        throw new HealthCheckError('Other service check failed', { 'other-service': { status: 'down', code, url } })
      }),

    ])
  }
}
 
diagnostics/diagnostics.module.ts
 import { Module } from '@nestjs/common'
import { TerminusModule } from '@nestjs/terminus'
import { HttpModule } from '@nestjs/axios'
import { HealthController } from './health/health.controller'

@Module({
  imports: [
    HttpModule,
    TerminusModule,
  ],
  controllers: [HealthController],
})
export class DiagnosticsModule { }