Search code examples
node.jsexpressgraphqlapolloapollo-server

how to set a middleware only for a specific resolver in Graphql backend using Apollo Express?


In Rest API, if you want to set a middleware just for a specific route, you can use this for example:

router
  .route('/top-5-cheap')
  .get(tourControllers.middleAliasApi, tourControllers.getAllTours);

so in this case, middleAliasApi middleware is executed only if the user sends a request to this route.

How can i do the same in Graphql app? For example, execute a middleware only if the user queries a specific resolver. I'm using Apollo-express-server in backend.


Solution

  • You can use graphql-middleware package. You can create middleware for the specific resolver. E.g.

    const { ApolloServer } = require('apollo-server');
    const { makeExecutableSchema } = require('@graphql-tools/schema');
    const { applyMiddleware } = require('graphql-middleware');
    
    // Minimal example middleware (before & after)
    const beepMiddleware = {
      Query: {
        hello: async (resolve, parent, args, context, info) => {
          // You can use middleware to override arguments
          const argsWithDefault = { name: 'Bob', ...args };
          const result = await resolve(parent, argsWithDefault, context, info);
          // Or change the returned values of resolvers
          return result.replace(/Trump/g, 'beep');
        },
        tours: async (resolve, parent, args, context, info) => {
          const result = await resolve(parent, args, context, info);
          return result.concat([4]);
        },
      },
    };
    
    const typeDefs = `
      type Query {
        hello(name: String): String
        tours: [Int]!
      }
    `;
    const resolvers = {
      Query: {
        hello: (parent, { name }, context) => `Hello ${name ? name : 'world'}!`,
        tours: () => [1, 2, 3],
      },
    };
    
    const schema = makeExecutableSchema({ typeDefs, resolvers });
    
    const schemaWithMiddleware = applyMiddleware(schema, beepMiddleware);
    
    const server = new ApolloServer({
      schema: schemaWithMiddleware,
    });
    
    server.listen({ port: 8008 }).then(() => console.log('Server started at http://localhost:8008'));
    

    Query result:

    ⚡  curl -H 'Content-Type: application/json' -X POST -d '{"query": "{ tours }"}' http://localhost:8008/graphql
    {"data":{"tours":[1,2,3,4]}}
    

    package versions:

    "graphql-middleware": "^3.0.3",
    "apollo-server": "^2.15.1",