{"id":17012,"library":"graphql-middleware","title":"GraphQL Middleware","description":"graphql-middleware is a schema wrapper designed to allow developers to compose reusable middleware functions around GraphQL resolvers. This utility enables the execution of arbitrary code both before and after a resolver is invoked, facilitating tasks such as argument modification, result transformation, logging, authentication, and error handling. The current stable version, 6.1.35, demonstrates ongoing maintenance with recent updates focused on bug fixes and dependency compatibility, particularly with newer GraphQL versions. Its release cadence is primarily driven by these maintenance needs rather than frequent new feature introductions. Key differentiators include its intuitive API, which offers complete control over the resolver lifecycle, and its broad compatibility with any standard GraphQL schema, integrating seamlessly with popular GraphQL server implementations like Apollo Server. This library promotes a clear separation of concerns, improving code structure by centralizing cross-cutting logic that would otherwise be duplicated across multiple resolvers. Developers can define middleware at various levels, from global application to specific fields, following an an \"onion\"-like execution principle.","status":"maintenance","version":"6.1.35","language":"javascript","source_language":"en","source_url":"https://github.com/maticzav/graphql-middleware","tags":["javascript","graphql","middleware","schema","resolvers","server","yoga","typescript"],"install":[{"cmd":"npm install graphql-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add graphql-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add graphql-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Core GraphQL library, required for schema definition and execution.","package":"graphql","optional":false}],"imports":[{"note":"The primary function to wrap a GraphQL schema with middleware. Use named import for ESM.","wrong":"const { applyMiddleware } = require('graphql-middleware');","symbol":"applyMiddleware","correct":"import { applyMiddleware } from 'graphql-middleware';"},{"note":"TypeScript interface for defining function-based middleware. Recommended for type safety.","symbol":"IMiddlewareFunction","correct":"import { IMiddlewareFunction } from 'graphql-middleware';"},{"note":"TypeScript interface for defining object-based middleware, allowing specific field targeting.","symbol":"IMiddleware","correct":"import { IMiddleware } from 'graphql-middleware';"}],"quickstart":{"code":"import { ApolloServer } from 'apollo-server';\nimport { makeExecutableSchema } from '@graphql-tools/schema';\nimport { applyMiddleware, IMiddlewareFunction, IMiddleware } from 'graphql-middleware';\n\nconst typeDefs = `\n  type Query {\n    hello(name: String): String\n    bye(name: String): String\n  }\n`;\n\nconst resolvers = {\n  Query: {\n    hello: (root: any, args: { name?: string }, context: any, info: any) => {\n      console.log(`3. resolver: hello`);\n      return `Hello ${args.name ? args.name : 'world'}!`;\n    },\n    bye: (root: any, args: { name?: string }, context: any, info: any) => {\n      console.log(`3. resolver: bye`);\n      return `Bye ${args.name ? args.name : 'world'}!`;\n    },\n  },\n};\n\n// Function-based middleware for logging input and result\nconst logInput: IMiddlewareFunction = async (resolve, root, args, context, info) => {\n  console.log(`1. logInput: ${JSON.stringify(args)}`);\n  const result = await resolve(root, args, context, info);\n  console.log(`5. logInput`);\n  return result;\n};\n\nconst logResult: IMiddlewareFunction = async (resolve, root, args, context, info) => {\n  console.log(`2. logResult`);\n  const result = await resolve(root, args, context, info);\n  console.log(`4. logResult: ${JSON.stringify(result)}`);\n  return result;\n};\n\nconst schema = makeExecutableSchema({ typeDefs, resolvers });\n\nconst schemaWithFunctionMiddleware = applyMiddleware(schema, logInput, logResult);\n\n// Object-based middleware for modifying arguments and results on specific fields\nconst beepMiddleware: IMiddleware = {\n  Query: {\n    hello: async (resolve, parent, args: { name?: string }, context, info) => {\n      // Override arguments\n      const argsWithDefault = { name: 'Bob', ...args };\n      const result = await resolve(parent, argsWithDefault, context, info);\n      // Modify returned value\n      return (result as string).replace(/Trump/g, 'beep');\n    },\n  },\n};\n\nconst finalSchema = applyMiddleware(schemaWithFunctionMiddleware, beepMiddleware);\n\nconst server = new ApolloServer({\n  schema: finalSchema,\n});\n\nasync function startServer() {\n  const { url } = await server.listen({ port: 8008 });\n  console.log(`🚀 Server ready at ${url}`);\n  console.log('Test queries:');\n  console.log('  query { hello(name: \"World\") }  // Expects \"Hello World!\" with logging');\n  console.log('  query { bye }                   // Expects \"Bye world!\" with logging');\n  console.log('  query { hello(name: \"Trump\") }  // Expects \"Hello beep!\" due to middleware');\n}\n\nstartServer();\n","lang":"typescript","description":"Demonstrates how to apply both function-based and object-based middleware to an executable GraphQL schema using Apollo Server, showcasing the 'onion' execution principle and resolver modification capabilities."},"warnings":[{"fix":"If introspection query interception is required, custom logic must be implemented outside graphql-middleware, or an older version (pre-3.0.0) must be used, though this is not recommended due to other potential issues.","message":"As of v3.0.0, graphql-middleware no longer wraps introspection queries. This means middleware will not run for introspection operations, which might affect security or logging mechanisms that relied on this behavior.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"For GraphQL Yoga users, refer to Yoga's documentation on schema wrapping or custom plugin integration to apply graphql-middleware manually. Older versions might retain direct Yoga support but are not recommended for new projects.","message":"Version 5.0.0 removed out-of-the-box support for GraphQL Yoga. If you are using GraphQL Yoga, you will need to manually integrate graphql-middleware with your Yoga schema, or consider alternatives if direct integration is critical.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Carefully consider the order of your middleware functions. Middleware that needs to execute before others (e.g., authentication) should be placed earlier in the array passed to `applyMiddleware`.","message":"Middleware execution follows an 'onion'-like principle: the first middleware in the array is the outermost layer (executed first and last), and subsequent middlewares are inner layers. Incorrect ordering can lead to unexpected behavior.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"When modifying `args` or `context`, consider immutability patterns where possible (e.g., creating new objects with spread syntax). Test thoroughly to ensure changes don't unintentionally impact other parts of your GraphQL execution flow.","message":"Modifying `args` or `context` objects within a middleware function can lead to side effects in subsequent resolvers or middleware if not managed carefully. Ensure modifications are intended and well-documented.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure that the first argument passed to `applyMiddleware` is the result of `makeExecutableSchema` or `buildSchema`, or another function that produces a `GraphQLSchema` instance.","cause":"The `applyMiddleware` function received an argument that is not a valid GraphQLSchema object.","error":"Error: Schema must be an instance of GraphQLSchema."},{"fix":"Verify that object-based middleware matches the schema structure (e.g., `Query`, `Mutation`, `Type.field`). For function-based middleware, always include `await resolve(root, args, context, info)` to ensure the next layer or the actual resolver is called.","cause":"This typically occurs when object-based middleware is incorrectly structured, or if middleware functions do not correctly call `await resolve(...)`.","error":"TypeError: Cannot read properties of undefined (reading 'Query') OR Middleware not applied."},{"fix":"Run `npm install graphql-middleware` or `yarn add graphql-middleware`. For TypeScript, ensure `tsconfig.json` includes `node_modules/@types` in its `typeRoots` (though usually default) and that the package is correctly installed.","cause":"The package is not installed, or TypeScript cannot locate its type definitions.","error":"Cannot find module 'graphql-middleware' or its corresponding type declarations."}],"ecosystem":"npm","meta_description":null}