jsondecode.com logo

JSON in Express.js — Request Parsing, Response Formatting, and Validation

Express.js has built-in support for JSON through its express.json() middleware and res.json() response helper. Setting up JSON parsing correctly is one of the first things you do when building an Express API.

Enabling JSON body parsing

Register express.json() as middleware before your routes. Without it, req.body will be undefined for JSON request bodies.

import express from "express";

const app = express();

// Must be registered before routes that read req.body
app.use(express.json());

app.post("/users", (req, res) => {
  console.log(req.body); // parsed JSON object
  res.status(201).json({ created: true });
});

app.listen(3000);

Sending JSON responses

Use res.json() to send a JSON response. It sets Content-Type: application/json and calls JSON.stringify() for you.

app.get("/users/:id", async (req, res) => {
  const user = await db.findUser(req.params.id);

  if (!user) {
    return res.status(404).json({ error: "User not found" });
  }

  res.json(user); // 200 OK with JSON body

  // For arrays:
  // res.json([user1, user2]);
});

Accessing nested JSON fields from req.body

Once express.json() is registered, req.body is a fully-parsed JavaScript object. Access nested fields with dot notation or destructuring.

app.post("/orders", (req, res) => {
  const { customerId, items, shipping } = req.body;

  // Access nested fields
  const city = req.body.shipping?.address?.city;

  // Guard against missing fields
  if (!customerId || !Array.isArray(items)) {
    return res.status(400).json({ error: "Missing required fields" });
  }

  res.status(201).json({ orderId: "ord_123", customerId });
});

Validating JSON with Zod

Always validate req.body before using it. Zod is a popular choice that works well with TypeScript — parse the body and return a 422 on validation failure.

import { z } from "zod";

const CreateUserSchema = z.object({
  name: z.string().min(1),
  email: z.string().email(),
  age: z.number().int().min(0).optional(),
});

app.post("/users", (req, res) => {
  const result = CreateUserSchema.safeParse(req.body);

  if (!result.success) {
    return res.status(422).json({
      error: "Validation failed",
      issues: result.error.issues,
    });
  }

  const user = result.data; // typed: { name: string; email: string; age?: number }
  res.status(201).json({ id: 1, ...user });
});

Handling JSON parse errors

When a client sends malformed JSON, express.json() throws a SyntaxError. Catch it with an Express error middleware (4-argument function) placed after your routes.

import { ErrorRequestHandler } from "express";

const jsonErrorHandler: ErrorRequestHandler = (err, req, res, next) => {
  if (err instanceof SyntaxError && "body" in err) {
    return res.status(400).json({
      error: "Invalid JSON",
      message: err.message,
    });
  }
  next(err);
};

// Register AFTER all routes
app.use(jsonErrorHandler);

// Generic error handler
app.use((err: Error, req, res, next) => {
  console.error(err);
  res.status(500).json({ error: "Internal server error" });
});

Frequently Asked Questions

How do I parse JSON request bodies in Express?

Add app.use(express.json()) before your routes. This registers middleware that parses incoming requests with Content-Type: application/json and populates req.body with the parsed object.

Why is req.body undefined in my Express route?

You likely forgot to register express.json() middleware, or registered it after your route definition. Middleware runs in the order it is registered — make sure app.use(express.json()) comes before your route handlers.

How do I send a JSON response in Express?

Use res.json(data). It automatically sets Content-Type: application/json, serialises the value, and ends the response. Chain res.status(code).json(data) to set a non-200 status code.

How do I validate JSON in Express?

Use Zod with safeParse(): const result = schema.safeParse(req.body). If result.success is false, return a 400/422 with result.error.issues. Alternatives include Joi, express-validator, and Yup.

How do I handle malformed JSON in Express?

Add a 4-argument error middleware after your routes: (err, req, res, next) => { if (err instanceof SyntaxError && 'body' in err) return res.status(400).json({ error: 'Invalid JSON' }); next(err); }.

Format and validate your JSON instantly

Free, no ads, no sign-up. Also converts JSON to TypeScript, YAML, CSV, and more.

Open JSON Formatter →

If jsondecode.com saved you time, share it with your team

Free forever. No ads. No sign-up. Help other developers find it.