Как получить обработчик маршрута в Nest JS Interceptor (как для Express, так и для Fastify) - PullRequest
1 голос
/ 07 марта 2020

У меня проблемы с попыткой удержать маршрут обработчика Nest JS в перехватчике, о котором я пишу. Например, если у контроллера есть такой маршрут:

  @Get('/params/:p1/:p2')
  routeWithParams(@Param() params): string {
    return `params are ${params.p1} and ${params.p2}`;
  }

Мне бы хотелось иметь возможность получить значение /param/:p1/:p2 программно. Использование URL-адреса и депараметризация НЕ являются опцией, поскольку на самом деле не существует способа сделать это на 100% герметично. Немного покопался и не нашел документированного способа захватить маршрут для обработчика. Хотите знать, если кому-то еще повезло? Вот пример кода, который я удалил из своего проекта:

import { Injectable, ExecutionContext, CallHandler, NestInterceptor } from '@nestjs/common';
import { Observable } from 'rxjs';
import { Request } from 'express';
import { FastifyRequest } from 'fastify';

function isExpressRequest(request: Request | FastifyRequest): request is Request {
  return (request as FastifyRequest).req === undefined;
}

@Injectable()
export class MyInterceptor implements NestInterceptor {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request: Request | FastifyRequest = context.switchToHttp().getRequest();

    if( !isExpressRequest(request) ) { // if req fufills the FastifyRequest interface, we will rename the transaction
      const req = request as FastifyRequest;
      const route = `` // TODO how can I grab the route either using the FastifyRequest or ExecutionContext??
    } // otherwise, we are in express request
    const route = `` // TODO how can I grab the route either using the Request or ExecutionContext?

    return next.handle();
  }
}

Если окажется, что перехватчик не сработает, и что-то еще, например гвардия, может сработать, чтобы получить эту информацию, я все уши.

1 Ответ

1 голос
/ 07 марта 2020

Поговорив с хорошими людьми в Гнезде JS Раздор, я указал на Reflectors. Таким образом, используя отражатель, я могу на самом деле получить данные пути, переданные в декоратор метода HTTP.

import { Injectable, ExecutionContext, CallHandler, NestInterceptor } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Observable } from 'rxjs';
import { Request } from 'express';
import { FastifyRequest } from 'fastify';
import { PATH_METADATA } from '@nestjs/common/constants';

function isExpressRequest(request: Request | FastifyRequest): request is Request {
  return (request as FastifyRequest).req === undefined;
}

@Injectable()
export class MyInterceptor implements NestInterceptor {
  constructor(private readonly reflector: Reflector) {}

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request: Request | FastifyRequest = context.switchToHttp().getRequest();

    const path = this.reflector.get<string[]>(PATH_METADATA, context.getHandler()); 
    const method = isExpressRequest(request) ? request.method : (request as FastifyRequest).req.method;

    // can now do something with the path and method

    return next.handle();
  }
}

Теперь существует обоснованная проблема, что ключ PATH_METADATA может перемещаться в Nest JS common, ломая этот код Абсолютно возможно и что-то, чтобы высматривать. Но тот факт, что в соответствии с виной git для констант, ключ пути не обновлялся в течение 3 лет, смягчает эти проблемы imo: https://github.com/nestjs/nest/blame/master/packages/common/constants.ts

...