Request Handlers in Express: req, res, and next Explained
Express handlers receive req, res, next. Here is what each does and how to use them.
Request Handlers in Express: req, res, and next
Every Express handler has the signature (req, res, next) => {}. Here is what each argument does.
req: The Incoming Request
The request object. Common fields:
req.body: parsed JSON body (after express.json middleware).req.params: URL params like /users/:id.req.query: query string like ?search=foo.req.headers: HTTP headers.req.cookies: parsed cookies (after cookie-parser).req.user: custom field set by an auth middleware.
res: The Outgoing Response
The response object. Common methods:
res.status(code): set status code. Chain with .json or .send.res.json(obj): send JSON.res.send(str): send plain text or HTML.res.redirect(path): redirect.res.cookie(name, value, options): set a cookie.res.clearCookie(name): clear a cookie.res.end(): end without a body.
next: Pass Control
Call next() to move to the next middleware or handler. Call next(err) to jump to the error handler.
router.get('/posts/:id', (req, res, next) => {
Post.findById(req.params.id, (err, post) => {
if (err) return next(err);
if (!post) return next(new ApiError(404, 'Post not found'));
res.json(post);
});
});
Common Handler Patterns
Send JSON
res.status(200).json({ user });
Create and Send 201
const user = await User.create(req.body);
res.status(201).json(user);
Set a Cookie and Respond
res.cookie('token', jwt, { httpOnly: true, secure: true, sameSite: 'lax' });
res.status(200).json({ user });
Handle Not Found
const user = await User.findById(req.params.id);
if (!user) return next(new ApiError(404, 'User not found'));
res.json(user);
Async Handlers
Use async/await. Wrap with an async handler to catch promise rejections:
const asyncHandler = fn => (req, res, next) =>
Promise.resolve(fn(req, res, next)).catch(next);
router.get('/users/:id', asyncHandler(async (req, res) => {
const user = await User.findById(req.params.id);
res.json(user);
}));
The Takeaway
Express handlers receive req (request data), res (response methods), and next (pass control or errors). Use req to read input, res to send output, and next to chain middlewares or report errors. Wrap async handlers to catch promise rejections.
req is the incoming request (body, params, query, headers, cookies). res is the outgoing response (status, json, send, cookie, redirect). next passes control to the next middleware or handler, or to the error handler with next(err).
Add app.use(express.json()) before routes, then read req.body. It is the parsed JSON object for any request with Content-Type: application/json.
Use res.cookie(name, value, options) before sending the response. For JWT, set httpOnly: true, secure: true, sameSite: 'lax'. Clear with res.clearCookie(name).
Call next(err) or throw an error. Express skips to the error-handling middleware (the one with four parameters: err, req, res, next).
Express 4 does not catch promise rejections from async handlers automatically. An asyncHandler wrapper catches the promise and passes errors to next. Express 5 catches async errors automatically, but the wrapper is still useful for older versions.
Ready to master Node.js completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master Node.js
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

