CodingNic

Middleware

Built-in Middleware

Middleware 10 min read

Built-in Middleware

Objectives

By the end of this lesson, you should be able to:

  • Use express.json() to parse JSON request bodies
  • Use express.urlencoded() to parse HTML form submissions
  • Recognize express.static() (Module 5) as another built-in middleware

💡 Why this matters: express.json() has already been used since Module 5 without being named as what it actually is, middleware. This lesson makes that explicit, and adds express.urlencoded() for the other common request body format, traditional HTML form submissions.

⚠️ A note on verification: every snippet and every response shown below was actually run and tested with real HTTP requests.

express.json() Is Middleware

javascript
app.use(express.json());

This exact line has appeared since Module 5, express.json() returns a middleware function, and app.use() registers it, exactly like the custom logger middleware from Lesson 1. It inspects the request’s Content-Type header, and if it’s application/json, parses the body and attaches the result to req.body, this is precisely how req.body becomes available in a route handler.

express.urlencoded() for Form Submissions

javascript
const express = require('express');
const app = express();

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.post('/json-body', (req, res) => {
  res.json({ received: req.body });
});

app.post('/form-body', (req, res) => {
  res.json({ received: req.body });
});

app.listen(4203);
bash
curl -X POST http://localhost:4203/json-body \
  -H "Content-Type: application/json" -d '{"name":"Sam"}'
text
{"received":{"name":"Sam"}}
bash
curl -X POST http://localhost:4203/form-body \
  -H "Content-Type: application/x-www-form-urlencoded" -d 'name=Sam&role=admin'
text
{"received":{"name":"Sam","role":"admin"}}

A traditional HTML <form> submission sends its data as Content-Type: application/x-www-form-urlencoded, not JSON, name=Sam&role=admin rather than {"name":"Sam"}. express.urlencoded({ extended: true }) parses this format into req.body, exactly the same shape as express.json() produces for JSON, { extended: true } allows nested objects and arrays in the parsed result, the standard setting for this option.

Multiple Body Parsers Can Coexist

Both express.json() and express.urlencoded() are commonly registered together, each only activates for requests with the matching Content-Type, a JSON request is unaffected by express.urlencoded() being registered, and vice versa, this is why server3.js above handles both /json-body and /form-body correctly from the same app.

express.static() Revisited

Module 5’s express.static(folderPath) is this exact same pattern, a built-in function that returns middleware, registered with app.use(). Recognizing express.json(), express.urlencoded(), and express.static() as three instances of the same underlying mechanism, rather than three unrelated features, is the real point of this lesson.

Try It

  1. Build a form (or simulate one with curl -d 'field=value' and the correct Content-Type header) and confirm express.urlencoded() parses it into req.body correctly.
  2. Register both express.json() and express.urlencoded() on the same app, and send one request of each type, confirming both are parsed correctly without interfering with each other.
  3. Remove express.urlencoded() temporarily, send a form-encoded request, and confirm req.body is now undefined or empty.
  4. Explain, in your own words, why express.static(), express.json(), and express.urlencoded() are all considered the same kind of thing, middleware, even though they do very different jobs.

Recap

  • express.json() parses a JSON request body into req.body, activating only for Content-Type: application/json requests.
  • express.urlencoded({ extended: true }) parses traditional HTML form submissions into req.body, in the same shape.
  • express.static(), express.json(), and express.urlencoded() are all built-in functions that return middleware, registered with app.use().

Next lesson: writing your own custom middleware.