RESTとは何か?

REST(Representational State Transfer)はプロトコルではなくアーキテクチャスタイルです。Webサービスの動作方法を規定する一連の制約を定義します。APIがこの制約に従っている場合、それをRESTfulと呼びます。重要な考え方はシンプルです:クライアントがリソースを表すURLにリクエストを送信し、サーバーがそのリソースの表現(通常はJSON)を返します。

RESTを定義する6つの制約は:クライアント・サーバー分離、ステートレス性、キャッシュ可能性、统一インターフェース、階層化システム、(オプションとしての)コードオンデマンドです。実務上、日常的に最も重要なのはステートレス性と統一インターフェースです。ステートレス性とは、各リクエストが処理に必要なすべての情報を含んでいる必要があるということで、サーバーはリクエスト間でセッション状態を保持しません。統一インターフェースとは、標準的なHTTPメソッドと予測可能なURLパターンを使用することです。

リソースの表現を含むRESTのクライアント・サーバーステートレスリクエスト・レスポンスサイクルを示す図

HTTPメソッドとその意味

HTTPメソッドは、リソースに対して実行するアクションをサーバーに伝えます。各メソッドには特定の意味があり、それを尊重する必要があります。これを無視すると、混乱を招き利用しにくいAPIになります。

GETは副作用なしにリソースを取得します。POSTは新しいリソースを作成します。PUTは既存のリソースを完全に置き換えます。PATCHはリソースの部分更新を行います。DELETEはリソースを削除します。

これらが典型的なusersリソースにどのように対応するかを示します:

text
GET /users → list all users
GET /users/42 → get user with id 42
POST /users → create a new user
PUT /users/42 → replace user 42 entirely
PATCH /users/42 → update specific fields of user 42
DELETE /users/42 → delete user 42

GETとDELETEは冪等性があります——複数回呼び出しても同じ結果になります。PUTも冪等性があります。POSTはそうではありません——2回呼び出すと通常2つのリソースが作成されます。

HTTPステータスコード

ステータスコードはクライアントに何が起きたかを知らせます。5つのクラスに分類されます:1xx 情報、2xx 成功、3xx リダイレクト、4xx クライアントエラー、5xx サーバーエラー。API開発で最もよく使うものは次のとおりです:

200 OK — リクエストが成功し、レスポンスボディがあることを示します。GETとPATCHの成功レスポンスに使用します。

201 Created — リソースが正常に作成されました。POSTが成功した後に使用します。新しいリソースを指すLocationヘッダーを含めます。

204 No Content — 成功しましたが、返すボディはありません。DELETEに使用します。

400 Bad Request — クライアントが無効なデータを送信しました(フィールド不足、型違い、検証失敗)。

401 Unauthorized — リクエストに有効な認証資格情報がありません。

403 Forbidden — クライアントは認証されていますが、権限がありません。

404 Not Found — リソースが存在しません。

409 Conflict — リクエストが現在の状態と競合しています(例:既存のメールアドレスでユーザーを作成しようとした場合)。

422 Unprocessable Entity — リクエストの形式は正しいですが、意味的な検証に失敗しました。

500 Internal Server Error — サーバーで何か問題が発生しました。本番環境でスタックトレースを露出させないでください。

Expressハンドラーでの具体的な例:

javascript
app.post('/users', (req, res) => {
const { email, name } = req.body;
if (!email || !name) {
return res.status(400).json({ error: 'email and name are required' });
}
// imagine createUser() saves to a database and returns the new record
const user = createUser({ email, name });
res
.status(201)
.location(`/users/${user.id}`)
.json(user);
});
HTTPステータスコード決定木のフローチャート:成功パス2xx vs クライアントエラー4xx vs サーバーエラー5xx

APIコンテキストにおけるHTTPヘッダー

ヘッダーはリクエストまたはレスポンスに関するメタデータを伝送します。REST APIにはいくつか essential なものがあります。

Content-Typeはリクエストまたはレスポンスボディのフォーマットを宣言します。JSON APIの場合、これは常にapplication/jsonです。`res.json()`を呼び出すとExpressはこれを自動的に設定しますが、生のレスポンスを構築する場合は明示的に設定する必要があります。

Acceptはクライアントが処理できるフォーマットをサーバーに伝えます。JSON APIを呼び出す際は、クライアントは`Accept: application/json`を送信するべきです。

Authorizationは資格情報を伝送します。REST APIで最も一般的なパターンはBearerトークン認証です:

text
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Cache-ControlはGETレスポンスのキャッシュ動作を指示します。めったに変わらない公開データの場合、`Cache-Control: public, max-age=300`を設定するとサーバーの負荷を軽減できます。ユーザー固有または機密データには、`Cache-Control: no-store`を使用してください。

Expressでは、`req.headers`で受信ヘッダーを読み取り、`res.set()`で送信ヘッダーを設定できます:

javascript
app.get('/products', (req, res) => {
const products = getProducts();
res
.set('Cache-Control', 'public, max-age=300')
.json(products);
});

まとめ

RESTは、ステートレスなクライアント・サーバー通信と统一インターフェースを基盤とするアーキテクチャスタイルです。HTTPメソッドはリソースに対するアクションを定義します——GETは読み取り、POSTは作成、PUTは置換、PATCHは更新、DELETEは削除。ステータスコードは結果を正確に伝えます:成功には2xx、クライアントのミスには4xx、サーバーの障害には5xx。ヘッダーはコンテンツタイプ、認証資格情報、キャッシュディレクティブなどのメタデータを伝えます。これらの基礎を正しく押さえることが、統合しやすいAPIと、コンシューマーに推測を強いるAPIを分かつのです。

レッスンのチェックポイント

1. 各リクエストが処理に必要なすべての情報を含んでいる必要があり、サーバーがリクエスト間でセッション状態を保持しないというRESTの制約はどれですか?

2. ユーザーのメールアドレスを部分的に更新し、ユーザー記録全体を置き換えたくないとします。最も適切なHTTPメソッドはどれですか?

3. 次のうち、冪等性がないHTTPメソッドはどれですか?

4. クライアントが新しいリソースを作成するためにPOSTリクエストを送信し、サーバーが成功しました。返すのに最も適切なステータスコードは何ですか?

5. ユーザーがログインしていますが、アクセス権のない管理者専用エンドポイントにアクセスしようとしています。サーバーはどのステータスコードを返すべきですか?

6. JSONレスポンスを期待していることをサーバーに伝えるために、クライアントはどのHTTPヘッダーを含めるべきですか?

7. レッスンのExpressの例では、`res.json()`は何を自動的に行い、通常は手動で設定する必要があるものは何ですか?