3秒でわかる
Express に組み込まれたミドルウェアで、リクエストの JSON 本文を解析して req.body にオブジェクトとして入れます。
もう少し詳しく
どういうものか
Express が標準で持つミドルウェア関数。app.use(express.json()) と登録しておくと、Content-Type が application/json のリクエストが届いたときに本文を読み取り、パースした結果を req.body に入れてくれる。内部では body-parser と同じ処理が動いており、Express 4.16 以降は追加インストールなしで使える。
ミドルウェアなので、登録した位置より後ろで定義したルートにだけ効く。
なぜ必要か
HTTP のリクエスト本文は、届いた時点ではバイト列が少しずつ流れてくるストリームでしかない。自前で扱うなら、data イベントを集めて連結し、文字列にしてから JSON.parse を呼ぶ必要がある。express.json() はその一連をまとめて引き受け、ルートの中では req.body.email のようにオブジェクトとして触れる状態にする。
具体例
const express = require("express");
const app = express();
app.use(express.json({ limit: "1mb" })); // ここより後のルートで有効
app.post("/api/users", (req, res) => {
const { name, email } = req.body; // すでにオブジェクト
if (!name || !email) {
return res.status(400).json({ error: "name と email は必須です" });
}
res.status(201).json({ id: 1, name, email });
});
// JSON の形が壊れているときは SyntaxError が飛ぶ
app.use((err, req, res, next) => {
if (err instanceof SyntaxError) {
return res.status(400).json({ error: "JSON の形式が不正です" });
}
next(err);
});
app.listen(3000);つまずきやすいところ
一番多いのが req.body が undefined になる症状。原因はほぼ 2 つで、app.use(express.json()) を書き忘れているか、ルート定義より後ろに書いているかになる。登録はルートより前に置く。
クライアント側の Content-Type ヘッダーが application/json になっていない場合も、本文は解析されない。fetch を使うなら headers に明示する必要がある。
HTML のフォームから送られる application/x-www-form-urlencoded 形式は express.json() では扱えない。その場合は express.urlencoded() を別に登録する。
limit の既定値は 100 kb で、それを超える本文は 413 で弾かれる。画像を Base64 で載せるような設計だと、ここで詰まる。
似た用語との違い
| ミドルウェア | 対応する Content-Type |
|---|---|
express.json() | application/json |
express.urlencoded() | application/x-www-form-urlencoded |
express.text() | text/plain |
express.static() | 本文ではなく静的ファイルの配信 |