Pino Logger GraphQL Middleware

raw JSON →
0.0.2 verified Thu Apr 23 auth: no javascript abandoned

This package, `graphql-pino-middleware`, provides a GraphQL middleware specifically designed to integrate the Pino logger into GraphQL resolvers. It aims to reduce boilerplate by automatically injecting a `pino` logger instance into the GraphQL context for each request, allowing resolvers to easily log relevant information without directly instantiating or managing logger instances. Currently at version 0.0.2, this package appears to be in an early development stage or possibly unmaintained given its very low version number and the lack of publicly available information regarding its release cadence or roadmap. Its primary differentiator is its direct, focused integration with `pino` and `graphql-middleware` for simple resolver instrumentation.

error TypeError: Cannot read properties of undefined (reading 'info') at hello (YOUR_RESOLVER_FILE.js:XX:YY)
cause The `logger` object was not correctly initialized or passed to `graphqlPinoMiddleware`, or the middleware was not correctly applied, preventing `context.logger` from being populated.
fix
Ensure graphqlPinoMiddleware is instantiated with a pino logger instance (const loggerMiddleware = graphqlPinoMiddleware({ logger });) and that this middleware instance is passed to applyMiddleware.
error Error: GraphQL middleware must be a function
cause You likely passed the `graphqlPinoMiddleware` function directly to `applyMiddleware` instead of calling it to create an instance of the middleware.
fix
Call graphqlPinoMiddleware() to get the middleware instance before passing it to applyMiddleware. For example: const loggerMiddleware = graphqlPinoMiddleware({ logger }); applyMiddleware(schema, loggerMiddleware);
error TypeError: (0 , graphql_pino_middleware_1.default) is not a function
cause This typically indicates a CommonJS module (`require`) trying to import an ESM default export incorrectly, or a general incorrect default import pattern.
fix
For ESM, use import graphqlPinoMiddleware from 'graphql-pino-middleware';. If using CommonJS and the package is ESM-only or uses default exports, you might need const graphqlPinoMiddleware = require('graphql-pino-middleware').default; if supported by your build setup.
breaking The package is currently at version 0.0.2, indicating an extremely early development stage. APIs are highly unstable and may change drastically without adhering to semantic versioning, leading to frequent breaking changes.
fix Thoroughly test after any update and review the source code for changes. Consider forking or contributing if long-term stability is required.
gotcha The middleware injects a logger into the GraphQL context. In complex scenarios involving async operations, `dataloader`, or other context-modifying patterns, ensure the logger instance or its context is correctly propagated or scoped to avoid unexpected logging behavior or data races.
fix Explicitly pass the logger to async functions or utilize tools like `async_hooks` for advanced context management if deep logging context is critical.
gotcha Enabling very verbose logging (e.g., logging every resolver call with extensive data) via Pino in a high-throughput GraphQL API can introduce significant performance overhead due to I/O operations and serialization. Configure Pino appropriately for your production environment.
fix Adjust Pino's logging level and avoid excessive data logging in production. Consider asynchronous logging transport for better performance, if supported by your Pino setup.
npm install graphql-pino-middleware
yarn add graphql-pino-middleware
pnpm add graphql-pino-middleware

This quickstart demonstrates how to set up `graphql-pino-middleware` with a basic Express GraphQL server, injecting a Pino logger into the GraphQL context for use within resolvers.

import express from 'express';
import graphqlExpressHttp from 'express-graphql';
import { applyMiddleware } from 'graphql-middleware';
import { makeExecutableSchema } from 'graphql-tools';
import pino from 'pino';
import graphqlPinoMiddleware from 'graphql-pino-middleware';

// 1. Create the pino logger
const logger = pino();

// 2. Create the graphql-pino-middleware instance
const loggerMiddleware = graphqlPinoMiddleware({
  logger
});

// 3. Define your GraphQL schema and resolvers
const typeDefs = `
  type Query {
    hello(name: String): String
  }
`;

const resolvers = {
  Query: {
    hello: (parent, args, context) => {
      const result = `Hello ${args.name ? args.name : 'world'}!`;
      // The logger is available in the context now, thanks to the middleware
      context.logger.info({
        helloResolver: result,
        name: args.name // Log resolver arguments
      });
      return result;
    }
  }
};

// 4. Apply the middleware to the schema
const schema = applyMiddleware(
  makeExecutableSchema({ typeDefs, resolvers }),
  loggerMiddleware
);

// 5. Set up your Express GraphQL server
const app = express();
app.use(
  '/graphql',
  graphqlExpressHttp({
    schema: schema,
    rootValue: resolvers,
    graphiql: true // Enable GraphiQL for easy testing
  })
);

// 6. Start the server
const port = process.env.PORT ?? 4000;
app.listen(port, () => {
  console.log(`🚀 Server ready at http://localhost:${port}/graphql`);
  logger.info(`GraphQL server running on http://localhost:${port}/graphql`);
});