📖 Scenario: You are building a simple GraphQL server for a bookstore. You want to add middleware to log each request's details before processing it.
🎯 Goal: Create a GraphQL server with middleware that logs the operation name and variables of each request.
📋 What You'll Learn
Create a basic GraphQL schema with a Query type that has a books field returning a list of books.
Add a middleware function that logs the operation name and variables of each incoming request.
Integrate the middleware into the GraphQL server setup.
Ensure the middleware runs before the resolver executes.
💡 Why This Matters
🌍 Real World
Middleware in GraphQL servers helps add features like logging, authentication, and validation without changing resolver logic.
💼 Career
Understanding server middleware is essential for backend developers working with GraphQL APIs to build secure and maintainable services.
Progress0 / 4 steps
1
Define the GraphQL schema
Create a GraphQL schema with a type Query that has a books field returning a list of Book objects. Define the Book type with id (ID), title (String), and author (String).
GraphQL
Hint
Use the gql tag to define your schema. Include Book and Query types exactly as described.
2
Create a middleware function
Create a middleware function called logMiddleware that takes resolve, parent, args, context, and info as parameters. Inside, log the info.operation.operation and args to the console, then call and return resolve(parent, args, context, info).
GraphQL
Hint
Define logMiddleware as an async function with the specified parameters. Use console.log to print operation and arguments, then call resolve.
3
Add resolver with middleware
Create a resolver object with a Query field. For books, wrap the resolver function with logMiddleware. The resolver should return an array of two books with exact values: { id: '1', title: '1984', author: 'George Orwell' } and { id: '2', title: 'Brave New World', author: 'Aldous Huxley' }.
GraphQL
Hint
Define resolvers with a Query object. Wrap the books resolver function with logMiddleware. Return the exact array of book objects.
4
Setup Apollo Server with middleware
Create an ApolloServer instance called server using typeDefs and resolvers. Export the server as the default export.
GraphQL
Hint
Import ApolloServer from apollo-server. Create server with typeDefs and resolvers. Export it using module.exports.
Practice
(1/5)
1. What is the main purpose of server middleware in a GraphQL server?
easy
A. To run code before GraphQL resolvers to manage requests
B. To define the GraphQL schema types
C. To execute database queries directly
D. To format the GraphQL query results
Solution
Step 1: Understand middleware role
Middleware runs before the main GraphQL code to handle requests.
Step 2: Identify middleware tasks
It can check, log, or modify requests before resolvers run.
Final Answer:
To run code before GraphQL resolvers to manage requests -> Option A
Quick Check:
Middleware manages requests before resolvers [OK]
Hint: Middleware runs before resolvers to manage requests [OK]
Common Mistakes:
Confusing middleware with schema definition
Thinking middleware executes database queries
Assuming middleware formats results
2. Which of the following is the correct way to call the next middleware function in a GraphQL server middleware?
easy
A. next();
B. continue();
C. proceed();
D. runNext();
Solution
Step 1: Recall middleware function signature
Middleware functions receive a next callback to continue processing.
Step 2: Identify correct call syntax
The standard call to continue is next(); exactly.
Final Answer:
next(); -> Option A
Quick Check:
Use next() to continue middleware chain [OK]
Hint: Call next() to continue middleware processing [OK]
Common Mistakes:
Using incorrect function names like continue()
Forgetting to call next() causing request hang
Calling next without parentheses
3. Given this middleware code snippet, what will be logged when a request is made?
First, 'Request received' logs before calling next().
Step 2: Understand next() behavior
After next() completes, 'Request processed' logs.
Final Answer:
Request received\nRequest processed -> Option B
Quick Check:
Logs before and after next() run in order [OK]
Hint: Logs before and after next() run in order [OK]
Common Mistakes:
Assuming next() blocks logging after it
Thinking logs reverse order
Ignoring that next() allows later code to run
4. Identify the error in this middleware code:
function authMiddleware(req, res, next) {
if (!req.user) {
res.status(401).send('Unauthorized');
}
next();
}
medium
A. req.user check should be after next()
B. Missing call to next() inside if block
C. res.status should be res.sendStatus
D. next() is called even after sending response
Solution
Step 1: Check flow after sending response
If !req.user, response is sent but next() still runs.
Step 2: Understand middleware flow control
Calling next() after sending response can cause errors or duplicate handling.
Final Answer:
next() is called even after sending response -> Option D
Quick Check:
Stop calling next() after response sent [OK]
Hint: Don't call next() after sending response [OK]
Common Mistakes:
Calling next() unconditionally after response
Not returning after sending response
Misplacing user check after next()
5. You want to add middleware that logs the request time and then modifies the request object to add a requestId before GraphQL resolvers run. Which middleware code correctly achieves this?
hard
A. function middleware(req, res, next) {
req.requestTime = Date.now();
next();
res.requestId = Math.random().toString(36).slice(2);
}
B. function middleware(req, res) {
req.requestTime = Date.now();
next();
req.requestId = Math.random().toString(36).slice(2);
}
C. function middleware(req, res, next) {
req.requestTime = Date.now();
req.requestId = Math.random().toString(36).slice(2);
next();
}
D. function middleware(req, res, next) {
next();
req.requestTime = Date.now();
req.requestId = Math.random().toString(36).slice(2);
}
Solution
Step 1: Ensure middleware modifies request before next()
Properties must be set on req before calling next() to be available in resolvers.
Step 2: Check correct use of next() and property assignment
function middleware(req, res, next) {
req.requestTime = Date.now();
req.requestId = Math.random().toString(36).slice(2);
next();
} sets both properties before next(), ensuring proper order and correct object.
Final Answer:
function middleware(req, res, next) {
req.requestTime = Date.now();
req.requestId = Math.random().toString(36).slice(2);
next();
} -> Option C
Quick Check:
Set req properties before next() call [OK]
Hint: Set req properties before next() to pass data [OK]
Common Mistakes:
Calling next() before setting properties
Modifying res instead of req for request data
Missing next() parameter or call
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.