es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El throttler de Nest js con GraphQL no está funcionando como se esperaba.

@Injectable()
export class GqlThrottlerGuard extends ThrottlerGuard {
getRequestResponse(context: ExecutionContext) {
const gqlCtx = GqlExecutionContext.create(context);
const ctx = gqlCtx.getContext();
return { req: ctx.req, res: ctx.res };
}
}

Aquí estoy obteniendo solo req de ctx, res es undefined. Estoy usando GraphQL con express en nestjs.

Así es como se ve mi objeto de contexto antes de crear un GqlExecutionContext:

    ExecutionContextHost {
  args: [
    undefined,
    { id: 2 },
    { req: [IncomingMessage] },
    {
      fieldName: 'user',
      fieldNodes: [Array],
      returnType: User!,
      parentType: Query,
      path: [Object],
      schema: [GraphQLSchema],
      fragments: [Object: null prototype] {},
      rootValue: undefined,
      operation: [Object],
      variableValues: {},
      cacheControl: [Object]
    }
  ],
  constructorRef: [class UsersResolver],
  handler: [Function: findOne],
  contextType: 'graphql'
}

Error:

[Nest] 30284  - 08/01/2022, 12:54:25 am   ERROR [ExceptionsHandler] No se puede leer la propiedad 'ip' de undefined
TypeError: No se puede leer la propiedad 'ip' de undefined
    en ThrottlerGuard.getTracker (C:\Users\Mahesh\OneDrive\Desktop\graphql-server\node_modules\@nestjs\throttler\dist\throttler.guard.js:95:16)
Tags:  , ,

Answer

  1. Avatar for davy.ai

    En este fragmento de código, la clase GqlThrottlerGuard extiende la clase ThrottlerGuard y anula su método getRequestResponse. El propósito de este método es devolver un objeto que contiene las propiedades req y res del objeto context pasado al guardia, que se puede utilizar para limitar las solicitudes al servidor.

    Sin embargo, en este caso particular, el objeto ctx solo contiene una propiedad req y la propiedad res es undefined. Esto se debe a que el objeto de contexto se crea utilizando GqlExecutionContext.create, que se utiliza específicamente para solicitudes de GraphQL en NestJS.

    En GraphQL, no hay un objeto de respuesta directa como en una API REST tradicional. En su lugar, los datos de respuesta se envían de vuelta al cliente como parte de la respuesta de GraphQL. Por lo tanto, el objeto res no está disponible en el objeto de contexto de GraphQL.

    Esto puede ser problemático cuando se extienden clases como ThrottlerGuard que esperan tener acceso tanto a las propiedades req como res del objeto de contexto. En este caso, la clase ThrottlerGuard intenta acceder a la propiedad ip del objeto req, lo que causa un TypeError ya que ctx.req es undefined.

    Para solucionar este problema, es posible que deba modificar la clase ThrottlerGuard para que funcione con solicitudes de GraphQL. Una posible solución es modificar el método getTracker de ThrottlerGuard para acceder a la dirección IP del cliente directamente desde el objeto de contexto de GraphQL:

    @Injectable()
    export class GqlThrottlerGuard extends ThrottlerGuard {
      getTracker(context: ExecutionContext): Promise<requestidentifier> {
        const gqlCtx = GqlExecutionContext.create(context);
        const clientIp = gqlCtx.getContext().request.connection.remoteAddress;
        // ...
      }
    }
    

    Este fragmento de código utiliza la propiedad request.connection.remoteAddress para extraer la dirección IP del cliente del objeto de contexto de GraphQL. Después de realizar este cambio, la clase ThrottlerGuard debería poder rastrear y limitar correctamente las solicitudes de GraphQL en NestJS.

Comments are closed.