入力検証
送られてきたものを信じない
第4章で出品の API を作りました。あのままだと、こういう商品が登録できてしまいます。
JSON
{ "name": "", "price": "たぶん5000くらい" }名前が空で、価格が文字列です。保存はできますが、一覧に空欄が並び、合計金額の計算も壊れます。
外から来るものは、正しい形とは限りません。 悪意がなくても、フォームの不具合や打ち間違いで届きます。だから受け取る側で確かめます。
何を確かめるか
見るべきことは、だいたい 3 つに分かれます。
| 観点 | 例 |
|---|---|
| 必須 | 名前が入っているか |
| 型 | 価格が数値か |
| 範囲 | 価格が 0 より大きいか |
順番も大切です。値が無いのに型を調べても意味がないので、必須から見ます。
おかしければ400
第4章のステータスコードで触れたとおり、送られた内容がおかしいときは 400 です。
JavaScript
app.post("/items", (req, res) => {
if (!req.body.name) {
return res.status(400).json({ error: "商品名は必須です" });
}
if (typeof req.body.price !== "number") {
return res.status(400).json({ error: "価格は数値で指定してください" });
}
// ここから先は、正しい値だと分かっている
});理由を書いて返す
{ "error": "入力が不正です" } だけでは、送った側は何を直せばよいのか分かりません。
どこがどうおかしいのかを書いて返します。それが分かるのは、確かめた側だけだからです。フリマの出品フォームなら、その文言をそのまま画面に出せます。
検証は入り口に集める
検証を通ったあとの処理では、もう値を疑いません。price は数値だと決まっているので、そのまま計算できます。
入り口で確かめ、奥では信じる。 この線引きがあると、奥の処理が読みやすくなります。逆に、あちこちで if (typeof price === "number") と書き始めたら、それは入り口の検証が足りていない印です。
手を動かす
演習では、出品の API に検証を足します。必須・型・範囲の 3 つを、順番に確かめてください。
要件
nameが無い・空文字なら 400 で{"error":"商品名は必須です"}priceが数値でなければ 400 で{"error":"価格は数値で指定してください"}priceが 0 以下なら 400 で{"error":"価格は1円以上にしてください"}、すべて通れば 201 で登録
入出力例
request("POST", "/items", {"name":"木製のスツール","price":3500}) → "201 {"id":2,"name":"木製のスツール","price":3500}"
request("POST", "/items", {"name":"","price":3500}) → "400 {"error":"商品名は必須です"}"
request("POST", "/items", {"name":"木製のスツール","price":"たぶん5000くらい"}) → "400 {"error":"価格は数値で指定してください"}"
request("POST", "/items", {"name":"木製のスツール","price":0}) → "400 {"error":"価格は1円以上にしてください"}"
request("POST", "/items", {"price":3500}) → "400 {"error":"商品名は必須です"}"ヒント
編集 ゆめさく編集部