Как записать все внешние запросы http Axios в NestJS - PullRequest
0 голосов
/ 17 января 2019

Я хочу иметь возможность регистрировать каждый запрос axios с полным URL, заголовками и т. Д., Но в настоящее время не нашел способа сделать это.

То, чего я добился до сих пор, - это перехват Http-перехватчика на основе этого ответа

export class HttpLoggerInterceptor implements NestInterceptor {
  intercept(
    context: ExecutionContext,
    call$: Observable<any>,
  ): Observable<any> {
    return call$.pipe(
      map(data => {
        // pipe call to add / modify header(s) after remote method
        const req = context.switchToHttp().getRequest();
        return data;
      }),
    );
  }
}

Теперь я просматриваю объекты req и context при отладке, но не вижу URL запроса Asios и т. Д. Если я не пропустил это.

Маршрут моего контроллера (в данном случае api/data) имеет число N внешних вызовов HTTP, но перехватчик перехватывает только вызов контроллера, а не вызовы Axios.

Есть мысли?

То есть context объект:

args:Array(2) [IncomingMessage, ServerResponse]
constructorRef:class AppController { … }
getRequest:() => …
getResponse:() => …
handler:data() { … }
__proto__:Object {constructor: , getClass: , getHandler: , …}

то есть req:

_dumped:false
_events:Object {}
_eventsCount:0
_maxListeners:undefined
_parsedOriginalUrl:Url {protocol: null, slashes: null, auth: null, …}
_parsedUrl:Url {protocol: null, slashes: null, auth: null, …}
_readableState:ReadableState {objectMode: false, highWaterMark: 16384, buffer: BufferList, …}
baseUrl:""
body:Object {}
client:Socket {connecting: false, _hadError: false, _handle: TCP, …}
complete:true
connection:Socket {connecting: false, _hadError: false, _handle: TCP, …}
destroyed:false
fresh:false
headers:Object {accept: "application/json, text/plain, */*", user-agent: "axios/0.18.0", host: "localhost:3000", …}
host:"localhost"
hostname:"localhost"
httpVersion:"1.1"
httpVersionMajor:1
httpVersionMinor:1
ip:"::ffff:127.0.0.1"
ips:Array(0)
method:"GET"
next:function next(err) { … }
originalUrl:"/api/data"
params:Object {}
__proto__:Object {constructor: , __defineGetter__: , __defineSetter__: , …}
path:"/api/data"
protocol:"http"
query:Object {}
rawHeaders:Array(8) ["Accept", "application/json, text/plain, */*", "User-Agent", …]
rawTrailers:Array(0) []
readable:true
readableBuffer:BufferList
readableFlowing:null
readableHighWaterMark:16384
readableLength:0
res:ServerResponse {_events: Object, _eventsCount: 1, _maxListeners: undefined, …}
route:Route {path: "/api/data", stack: Array(1), methods: Object}
secure:false
socket:Socket {connecting: false, _hadError: false, _handle: TCP, …}
stale:true
statusCode:null
statusMessage:null
subdomains:Array(0)
trailers:Object {}
upgrade:false
url:"/api/data"
xhr:false

Ответы [ 2 ]

0 голосов
/ 28 июня 2019
npm i @types/morgan

npm i morgan

затем

import * as morgan from 'morgan';

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer
      .apply(morgan('combined'))
      .forRoutes('*');
  }
}
0 голосов
/ 17 января 2019

Nest.js-Interceptors только обрабатывает запрос, обработанный вашим контроллером, и ответ отправляется.Если вы выполняете http-запросы с Axios во время обработки запроса контроллера, они не будут обрабатываться перехватчиком.


Axios Interceptor

HttpService выставляет свой axiosэкземпляр напрямую через get axiosRef().С его помощью вы можете добавить axios interceptor:

this.httpService.axiosRef.interceptors.request.use(config => console.log(config));

Например, вы можете сделать это в onModuleInit() вашего AppModule.


Делегирование на фасад

В качестве альтернативы вы можете создать HttpService фасад, который регистрирует запрос и делегирует все вызовы встроенному HttpService:

@Injectable()
export class MyHttpService {
  private logger: Logger = new Logger(MyHttpService.name);

  constructor (private httpService: HttpService) {}

  public get<T = any>(url: string, config?: AxiosRequestConfig): Observable<AxiosResponse<T>> {
    this.logger.log({url, config});
    return this.httpService.get(url, config)
       .pipe(tap(response => this.logger.log(response)));
  }

  // ... all the other methods you need.

}

Вы можете создать свой собственный LoggingHttpModule, который импортирует встроенный HttpModule и экспортирует ваш MyHttpService.

...