Facebook Pixel

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.

Please Login.
Please Login.
Please Login.
Please Login.