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.
CodePudding user response:
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",