#105 0円出品が通ってしまう
中段 / 目安 25分
Issue #105 0円出品が通ってしまう
報告者: 凛(テックリード)
「昨夜、0円出品が3件登録されました。POST /items の検証が甘い。タイトル必須・価格は1円以上・型チェック。400 とエラー理由を返す形で塞いでください」
0円出品そのものより深刻なのは、それが登録できてしまうことです。データベースに入ってしまえば、集計も検索も、その先の処理がすべて汚染されます。
止めるのは入口です。見るべきことは3つに分かれます。
| 観点 | 例 |
|---|---|
| 必須 | タイトルが入っているか |
| 型 | 価格が数値か |
| 範囲 | 価格が1円以上か |
順番も決まっています。 値が無いのに型は調べられませんし、型が数値だと分かっていないのに大小は比べられません。土台から順に見ます。
"3500" のような文字列を弾くのを忘れないでください。"3500" > 0 は成り立ってしまうので、範囲だけ見ていると通り抜けます。
返すのは 400 と理由です。凛さんは「理由を配列で返すと親切」と言い添えました。問題が複数あるなら全部まとめて返すという考え方です。1つ直すたびに送り直すのは、送る側にとって手間だからです。
完成条件
POST /items に検証を足してください。
問題があれば 400 で {"errors":["タイトルは必須です"]} の形で返します。当てはまるものは全部入れてください。
| 条件 | 文言 |
|---|---|
title が無い・空文字 | タイトルは必須です |
price が数値でない | 価格は数値で指定してください |
price が数値で 0 以下 | 価格は1円以上にしてください |
並びはこの順です。すべて通れば 201 で {"id":3,"title":"...","price":...} を返します。id は「いまある最大の id + 1」です。
要件
- 問題を配列に集めて、1件でもあれば 400 で
{"errors":[...]}を返す priceが数値でないときは範囲の判定をしない(文字列の"3500"も弾く)- 通れば 201 で
{id, title, price}を返し、id は最大の id + 1 にする
入出力例
request("POST", "/items", {"price":3500,"title":"木製のスツール"}) → "201 {"id":3,"title":"木製のスツール","price":3500}"
request("POST", "/items", {"price":0,"title":"木製のスツール"}) → "400 {"errors":["価格は1円以上にしてください"]}"
request("POST", "/items", {"price":"3500","title":"木製のスツール"}) → "400 {"errors":["価格は数値で指定してください"]}"
request("POST", "/items", {"price":3500,"title":""}) → "400 {"errors":["タイトルは必須です"]}"
request("POST", "/items", {"price":-100,"title":""}) → "400 {"errors":["タイトルは必須です","価格は1円以上にしてください"]}"
request("POST", "/items", {}) → "400 {"errors":["タイトルは必須です","価格は数値で指定してください"]}"ヒント
前のヒントを開くと次が開きます。開かずに解けると未開封クリアです
ヒント 2ヒント 1 を開くと読めます
ヒント 3ヒント 2 を開くと読めます
編集 ゆめさく編集部