はじめに
すべての実用的なAPIは、クライアントからデータを受信する必要があります — URLに含まれるユーザーID、クエリ文字列のフィルターオプション、フォームデータを含むJSONボディなど。CRUDエンドポイントを構築する前に、Expressが受信データの各部分をどこに配置し、それを確実に読み取る方法を知っておく必要があります。
このレッスンでは、3つの主要な入力ソース — URLパラメータ、クエリ文字列、リクエストボディ — を取り上げ、それらすべてを単純なリソース用の完全なCRUDエンドポイントセットで活用します。
入力の読み取り:パラメータ、クエリ文字列、ボディ
Expressは受信リクエストデータを、リクエストオブジェクト上の3つの異なるオブジェクトに解析します。
URLパラメータはパスの名前付きセグメントです。ルート定義でコロンを使用して宣言し、Expressはそれらをreq.paramsで利用できるようにします。
クエリ文字列はURLの疑問符の後に表示されます。例:`/users?role=admin&limit=10` の形式です。Expressはこれらを自動的にreq.queryに解析します。
リクエストボディはクライアントから送信される構造化データを運びます。多くの場合JSON形式です。Expressはデフォルトではボディを解析しないため、ルートより前に組み込みのexpress.json()ミドルウェアを登録する必要があります。
このミドルウェアが配置されると、POSTやPUTのペイロードがreq.bodyで利用可能になります。
完全なCRUD APIの構築
ルーティングの仕組みに焦点を当てるため、以下の例ではデータストアとしてインメモリ配列を使用しています。実際のプロジェクトでは、配列の操作をデータベース呼び出しに置き換えることになります。
データとID生成用のヘルパーから始めましょう:
Create — POST /users はボディを読み取り、新しいレコードをプッシュします:
Read all — GET /users はクエリ文字列によるroleでのオプションのフィルタリングをサポートします:
Read one — GET /users/:id は req.params を使用して単一のレコードを検索します:
Update — PUT /users/:id はパラメータ(どのレコードか)とボディ(新しい値)を組み合わせます:
Delete — DELETE /users/:id はレコードを削除し、204 No Contentを返します:
よくある間違い
express.json()を忘れることは、初心者にとって最も頻繁な混乱の原因です。req.bodyがundefinedの場合、ミドルウェアが登録されているか、クライアントがContent-Type: application/jsonヘッダーを送信しているかを確認してください。
req.params.idを比較する前に数値に変換しないことも、別の微妙なバグです。ルートパラメータは常に文字列です。文字列の「1」と数値の1を厳密等価演算子で比較すると常にfalseになるため、findやfindIndexの呼び出しではすべてのレコードが静かにミスされます。
レスポンスを送信した後にデータを返すと、Expressで「headers already sent」エラーが発生します。条件文の中でres呼び出しの前に必ずreturnを使用してください。上記の例で示されている通りです。
まとめ
Expressは受信リクエストデータを3つのオブジェクトに分割します:URLセグメント用のreq.params、クエリ文字列用のreq.query、解析されたJSONペイロード用のreq.body。express.json()ミドルウェアを登録することでボディの解析が有効になります。3つの入力ソースを理解した上で、標準的なCRUDエンドポイントを構築するには、HTTPメソッドとステータスコードを正しいデータ操作に対応付けるだけです — POSTと201を作成に、GETを読み取りに、PUTを更新に、DELETEと204を削除に。
レッスンのチェックポイント
学んだ内容を復習し、回答へのフィードバックを受けましょう。