Middleware и разбор JSON

Конвейер обработки запроса: как Express пропускает запрос через цепочку функций.

Middleware (промежуточный обработчик) — это функция, которая получает запрос, что-то с ним делает и передаёт дальше по цепочке через вызов next().

Запрос идёт через конвейер

В Express запрос проходит через цепочку middleware-функций, прежде чем дойдёт до финального обработчика маршрута. Каждая функция получает req, res и третий аргумент next — вызов next() передаёт управление следующему звену:

const express = require("express");
const app = express();

// middleware-логгер: сработает на каждый запрос
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next(); // передаём дальше
});

app.get("/", (req, res) => {
  res.send("Готово");
});

app.listen(3000);

На каждый запрос сначала отработает логгер (напечатает метод и путь), затем — обработчик маршрута. Если забыть next(), запрос «зависнет» — цепочка не продолжится.

Разбор тела: express.json()

Когда клиент шлёт POST с JSON-телом, по умолчанию Express его не понимает — тело приходит потоком. Встроенный middleware express.json() читает тело и кладёт разобранный объект в req.body:

const express = require("express");
const app = express();

app.use(express.json()); // включаем разбор JSON-тела

app.post("/users", (req, res) => {
  // теперь req.body — это объект из присланного JSON
  const name = req.body.name;
  res.send("Создан пользователь: " + name);
});

app.listen(3000);

Без app.use(express.json()) поле req.body будет undefined — это очень частая ошибка новичков.

Виды middleware

Где применяютПример
глобально (на всё)app.use(express.json())
на один маршрутapp.get("/", auth, handler)
встроенныеexpress.json(), express.static()
сторонниеcors, morgan, helmet

Middleware — это цепочка функций

Суть middleware — прогнать запрос через массив функций, передавая управление дальше. Эту идею легко смоделировать на чистом JS:

function runMiddlewares(request, middlewares) {
  let index = 0;
  function next() {
    if (index < middlewares.length) {
      const fn = middlewares[index++];
      fn(request, next); // вызываем звено, даём ему next
    }
  }
  next();
}

const log = (req, next) => { console.log("LOG:", req.url); next(); };
const auth = (req, next) => { req.user = "Аня"; next(); };
const handler = (req) => console.log("Ответ для", req.user, "на", req.url);

runMiddlewares({ url: "/profile" }, [log, auth, handler]);

Вывод:

LOG: /profile
Ответ для Аня на /profile

Видно, как каждая функция что-то добавляет к запросу (логирует, прописывает пользователя) и передаёт его дальше через next.

Итог

  • Middleware — функция (req, res, next) в конвейере обработки запроса.
  • next() передаёт управление дальше; без него запрос зависнет.
  • app.use(express.json()) разбирает JSON-тело в req.body.
  • Middleware бывают глобальные, на маршрут, встроенные и сторонние.
Проверьте себя
1. Что делает вызов next() внутри middleware?
AЗавершает ответ
BПередаёт управление следующему middleware в цепочке
CПерезапускает сервер
DОтменяет запрос
2. Зачем нужен app.use(express.json())?
AЧтобы отдавать статические файлы
BЧтобы разбирать JSON-тело запроса в req.body
CЧтобы включить HTTPS
DЧтобы логировать запросы
3. Чему будет равен req.body, если забыть подключить express.json()?
AПустой строке
Bundefined
CСырому потоку байтов
DОшибке 500
Поддержать проект