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.

Cómo inyectar un valor a través del middleware en el cuerpo de una consulta GraphQL (prisma-typegraphql)?

Actualmente estoy usando prisma-typegraphql para generar un esquema y sus propiedades.

Problema:
¿Hay alguna manera de escribir un middleware que acceda a un valor desde una fuente arbitraria y lo inyecte en los argumentos de la consulta de graphql? Debe ser pasado al resolutor de una manera que parezca que los datos han estado en la consulta desde el inicio y no se necesita modificar el resolutor.

Más información:
Digamos que tengo tres modelos: Cliente, Proyecto y Usuario. El Proyecto tiene una relación con el cliente a través de su id, identificando al cliente al que pertenece el proyecto, lo mismo sucede con el usuario.

modelo Cliente {
   id
   nombre
   etc...
}

modelo Usuario {
   id
   nombre
   clientId / cliente
   etc...
}

modelo Proyecto {
   id
   título
   clientId / cliente
   etc...
}

No quiero el clientId desde el frontend a través de la consulta, en su lugar, pretendo verificar al usuario que hace la solicitud y luego obtener el clientId de ese usuario. Actualmente mi middleware de autenticación verifica al usuario y luego pasa el objeto de usuario a lo largo del contexto. Sin embargo, debido a la naturaleza generada de los resolutores typegraphql-prisma, no puedo utilizar el contexto para inyectar los datos en el resolutor sin extender cada resolutor individual.

Prefiero inyectar el valor que quiero en la consulta de graphql antes de que llegue al resolutor, para que el resolutor no tenga idea de que algo cambió y procese la consulta como se pretendía.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Solución: Sí, es posible escribir un middleware que acceda a un valor desde una fuente arbitraria e inyecte ese valor en los argumentos de la consulta de GraphQL. El middleware puede crearse utilizando la librería ‘graphql-middleware’, la cual permite escribir middleware personalizado para consultas de GraphQL.

    En primer lugar, necesitaríamos crear un middleware que recupere el ID de cliente a partir del objeto de usuario en el contexto e inyecte ese ID en los argumentos de la consulta de GraphQL. Aquí hay un ejemplo:

    import { MiddlewareFn } from 'type-graphql';
    
    const injectClientIdMiddleware: MiddlewareFn = async ({ args, context }, next) => {
      const { user } = context;
    
      if (!user) {
        throw new Error('Usuario no autenticado');
      }
    
      // Inyectar el ID de cliente en cada argumento que tenga una propiedad clientId
      Object.values(args).forEach((arg: any) => {
        if (arg && arg.clientId) {
          arg.clientId = user.clientId;
        }
      });
    
      return next();
    };
    

    En este middleware, primero verificamos si el usuario está autenticado y recuperamos el ID de cliente desde el objeto de usuario. Luego, inyectamos ese ID en cada argumento que tenga una propiedad ‘clientId’. Esto asegurará que el ID de cliente se agregue a cada consulta que lo necesite.

    A continuación, necesitaríamos aplicar este middleware a nuestro servidor de GraphQL para que se ejecute antes del resolver. Aquí hay un ejemplo:

    import { applyMiddleware } from 'graphql-middleware';
    import { generateSchema } from 'typegraphql-prisma';
    import { prisma } from './prisma-client';
    import { injectClientIdMiddleware } from './middleware/injectClientIdMiddleware';
    
    const schema = generateSchema({
      prismaClient: prisma,
      emitSchemaFile: true,
      // Aplicar middleware a todas las consultas y mutaciones
      middleware: [injectClientIdMiddleware],
    });
    

    En este ejemplo, estamos aplicando el middleware injectClientIdMiddleware a todas las consultas y mutaciones utilizando graphql-middleware. Esto asegura que el middleware se ejecute antes del resolver e inyecte el ID de cliente en los argumentos de la consulta de GraphQL.

    Al hacer esto, hemos inyectado el valor que queremos en la consulta de GraphQL antes de que llegue al resolver, por lo que el resolver no tiene idea de que algo ha cambiado y procesa la consulta como se pretendía.

Comments are closed.