要約
REST APIのURLは、動詞(アクション)ではなく名詞(リソース)を含むべきです。HTTPメソッド(GET、POST、PUT、DELETE)が動詞の役割を果たします。/getUserや/createOrderのようなアクション動詞を使用することは、RESTの原則に反し、一貫性を損ない、APIの保守を困難にします。Modern PetstoreAPIは、全体を通じてリソース指向のURLを使用しています。
はじめに
ペットをステータスで検索するAPIエンドポイントを設計しているとします。最初に思いつくのは:GET /findPetsByStatus?status=availableかもしれません。これは説明的で分かりやすく、何をするか正確に示しています。しかし、これは間違いです。
REST APIはURLに動詞ではなく名詞を使用すべきです。HTTPメソッドが動詞の役割を果たします。GET /pets?status=availableが正しい設計です。URLはリソース(ペット)を表し、メソッドはアクション(取得)を表します。
以前のSwagger Petstoreでは、/pet/findByStatusや/pet/findByTagsのようなエンドポイントでこの間違いを犯していました。URL内のこれらのアクション動詞はRESTの原則に違反し、保守上の問題を引き起こします。Modern PetstoreAPIは、一貫してリソース指向のURLを使用することでこれを修正しています。
このガイドでは、なぜ動詞がREST URLに属さないのか、リソース指向のエンドポイントを設計する方法、そしてModern PetstoreAPIがこれをどのように正しく実装しているかを学びます。
REST APIにおける動詞の問題
URL内のアクション動詞は、RESTの用語ではなくRPC(Remote Procedure Call)の用語で考えていることを示します。
RPCスタイルのURL(誤り)
POST /createUser
GET /getUser?id=123
PUT /updateUser
DELETE /deleteUser?id=123
GET /findUsersByRole?role=admin
POST /sendEmail
GET /calculateTotal
これらのURLはアクションを記述しています。createUser()、getUser()、sendEmail()のような関数呼び出しのように読めます。
RESTスタイルのURL(正しい)
POST /users
GET /users/123
PUT /users/123
DELETE /users/123
GET /users?role=admin
POST /emails
GET /orders/123/total
これらのURLはリソースを記述しています。HTTPメソッドがアクションを提供します。
なぜこれが重要なのか
一貫性: REST URLは予測可能なパターンに従います。リソース名を知れば、すべてのエンドポイントが分かります。
GET /pets- ペットを一覧表示POST /pets- ペットを作成GET /pets/{id}- ペットを取得PUT /pets/{id}- ペットを更新DELETE /pets/{id}- ペットを削除
動詞ベースのURLでは、すべてのエンドポイントがユニークです。従うべきパターンがありません。
スケーラビリティ: APIが成長するにつれて、動詞ベースのURLが増加します。
/findPetsByStatus/findPetsByTags/findPetsByOwner/findPetsByBreed/searchPets/queryPets
リソース指向のURLはクエリパラメータを使用します。
GET /pets?status=availableGET /pets?tags=friendlyGET /pets?owner=johnGET /pets?breed=labrador
1つのエンドポイントですべてのフィルタリングを処理します。
HTTPメソッドが動詞である理由
RESTはHTTPに組み込まれた動詞を活用します。独自の動詞を発明する必要はありません。
HTTPメソッドとCRUD操作のマッピング
POST → 作成 (Create)
GET → 読み取り (Read)
PUT → 更新 (replace) (Update)
PATCH → 更新 (partial) (Update)
DELETE → 削除 (Delete)
これらのメソッドには定義されたセマンティクスがあります。GETは安全で冪等です。POSTはリソースを作成します。DELETEはリソースを削除します。
例:ユーザー管理
誤り(URLに動詞):
POST /createUser
GET /getUser?id=123
POST /updateUser
POST /deleteUser
すべての操作が異なるURLを使用します。HTTPメソッドは意味を伝えません。
正しい(HTTPメソッドを動詞として):
POST /users ← ユーザーを作成
GET /users/123 ← ユーザーを取得
PUT /users/123 ← ユーザーを更新
DELETE /users/123 ← ユーザーを削除
URLは同じままで、メソッドが変わります。
HTTPメソッドを使用する利点
1. キャッシング: GETリクエストはキャッシュ可能です。ブラウザやプロキシはこれを知っています。POST /getUserを使用すると、キャッシングが機能しません。
2. 冪等性: PUTとDELETEは冪等です。複数回呼び出しても、1回呼び出すのと同じ効果があります。これはリトライロジックにおいて重要です。
3. 安全性: GETは安全です。状態を変更しません。ツールやクローラーは安全にGETエンドポイントを呼び出すことができます。
4. 標準準拠: HTTPクライアント、プロキシ、キャッシュはHTTPメソッドを理解します。彼らはカスタム動詞を理解しません。
Swagger Petstoreの実際の例
以前のSwagger Petstoreには、動詞ベースのエンドポイントがいくつか含まれています。
例1:ステータスによるペットの検索
Swagger Petstore(誤り):
GET /pet/findByStatus?status=available
問題点:
findByStatusは動詞句です/pet/{id}エンドポイントとの一貫性がありません- 簡単に拡張できません(他の基準による検索はどうでしょうか?)
Modern PetstoreAPI(正しい):
GET /pets?status=AVAILABLE
利点:
- リソース指向(
/pets) - フィルタリングにクエリパラメータを使用
- 他のエンドポイントとの一貫性
- 簡単に拡張可能:
GET /pets?status=AVAILABLE&species=dog
完全な実装については、Modern PetstoreAPI RESTドキュメントを参照してください。
例2:タグによるペットの検索
Swagger Petstore(誤り):
GET /pet/findByTags?tags=tag1,tag2
Modern PetstoreAPI(正しい):
GET /pets?tags=friendly,trained
例3:ユーザーログイン
Swagger Petstore(誤り):
GET /user/login?username=john&password=secret
複数の問題点:
loginは動詞です- 認証に
GETを使用(セキュリティ上の問題) - URLクエリパラメータにパスワードを含める
Modern PetstoreAPI(正しい):
POST /auth/login
Content-Type: application/json
{
"username": "john",
"password": "secret123"
}
利点:
- リソース指向(
/auth) - 正しいHTTPメソッド(
POST) - URLではなくリクエストボディに認証情報
- 以降のリクエスト用にJWTトークンを返す
Modern PetstoreAPIがこれを修正する方法
Modern PetstoreAPIは、全体を通じてリソース指向のURLを使用しています。
ペット管理
GET /pets ← 全てのペットを一覧表示
GET /pets?status=AVAILABLE ← ステータスでフィルタリング
GET /pets?species=dog ← 種別でフィルタリング
GET /pets/{id} ← 特定のペットを取得
POST /pets ← 新しいペットを作成
PUT /pets/{id} ← ペットを更新
PATCH /pets/{id} ← 部分的な更新
DELETE /pets/{id} ← ペットを削除
動詞はありません。ただリソースとHTTPメソッドがあるだけです。
注文管理
GET /orders ← 注文を一覧表示
GET /orders/{id} ← 注文を取得
POST /orders ← 注文を作成
PUT /orders/{id} ← 注文を更新
DELETE /orders/{id} ← 注文をキャンセル
GET /orders/{id}/items ← 注文アイテムを取得
複雑な操作
CRUDにきれいにマッピングできない操作の場合、Modern PetstoreAPIはサブリソースを使用します。
POST /orders/{id}/payment ← 注文の支払いを処理
POST /orders/{id}/shipment ← 注文の出荷を作成
POST /pets/{id}/adoption ← 譲渡プロセスを開始
これらも依然としてリソース指向です。/orders/{id}/paymentは、注文に対する支払いリソースを表します。
動詞が必要に見えるとき
一部の操作はCRUDモデルに適合しません。URLに動詞を含めずにこれらを処理する方法を説明します。
検索操作
誤り:
GET /searchPets?query=labrador
正しい選択肢1(クエリパラメータ):
GET /pets?search=labrador
正しい選択肢2(検索リソース):
GET /pets/search?q=labrador
正しい選択肢3(QUERYメソッド):
QUERY /pets
Content-Type: application/json
{
"query": "labrador",
"filters": {
"status": "AVAILABLE"
}
}
Modern PetstoreAPIは、複雑さによってこれら3つのパターンすべてをサポートしています。
計算
誤り:
GET /calculateShipping?weight=10&destination=NY
正しい:
GET /shipping-estimates?weight=10&destination=NY
リソースは「配送見積もり」であり、計算アクションではありません。
バッチ操作
誤り:
POST /batchDeletePets
正しい:
DELETE /pets?ids=1,2,3
またはバッチリソースを使用します。
POST /pets/batch-operations
Content-Type: application/json
{
"operation": "delete",
"ids": [1, 2, 3]
}
状態を変更するアクション
誤り:
POST /activateUser
POST /deactivateUser
正しい:
PATCH /users/{id}
Content-Type: application/json
{
"status": "ACTIVE"
}
状態変更は、リソースに対する更新です。
Apidogを使ったURL設計のテスト
Apidogは、REST APIの設計を検証し、URL内の動詞の使用を検出するのに役立ちます。
Modern PetstoreAPIをインポート
- Modern PetstoreAPIのOpenAPI仕様をインポートします
- Apidogは自動的にテストケースを生成します
- エンドポイントの構造と命名を確認します
URL内の動詞を確認する
Apidogでカスタム検証ルールを作成します。
// URLに一般的なアクション動詞が含まれているかを確認します
const verbs = ['get', 'create', 'update', 'delete', 'find', 'search',
'calculate', 'process', 'send', 'fetch'];
const url = request.url.toLowerCase();
for (const verb of verbs) {
if (url.includes(`/${verb}`)) {
throw new Error(`URL contains verb: ${verb}. Use resource-oriented URLs instead.`);
}
}
エンドポイントの一貫性をテストする
Apidogは、関連するエンドポイントが一貫したパターンに従っていることを検証できます。
✓ GET /pets
✓ POST /pets
✓ GET /pets/{id}
✓ PUT /pets/{id}
✓ DELETE /pets/{id}
すべて同じ基本リソース(/pets)を使用しています。
Modern PetstoreAPIと比較する
Modern PetstoreAPIを参考にします。
- 独自のAPIとModern PetstoreAPIの両方をApidogにインポートします
- エンドポイントの構造を並べて比較します
- 一貫性のない点や動詞の使用を特定します
- REST原則に合うようにAPIをリファクタリングします
移行戦略
URLに動詞を含む既存のAPIがある場合、その移行方法を説明します。
戦略1:バージョン管理
正しいURLで新しいAPIバージョンを作成します。
# 古いAPI (v1)
GET /api/v1/findPetsByStatus?status=available
# 新しいAPI (v2)
GET /api/v2/pets?status=available
後方互換性のためにv1を維持し、v2への移行を推奨します。
戦略2:エイリアシング
古いURLと新しいURLの両方を一時的にサポートします。
# 古いURL(非推奨)
GET /pet/findByStatus?status=available
# 新しいURL(推奨)
GET /pets?status=available
レスポンスに非推奨警告を返します。
{
"data": [...],
"warnings": [
{
"code": "DEPRECATED_ENDPOINT",
"message": "このエンドポイントは非推奨です。代わりに GET /pets?status=available を使用してください。",
"sunset": "2027-01-01"
}
]
}
戦略3:リダイレクト
シンプルな移行にはHTTP 301リダイレクトを使用します。
GET /pet/findByStatus?status=available
→ 301 Moved Permanently
Location: /pets?status=available
これはGETリクエストには機能しますが、POST、PUT、DELETEには機能しません。
まとめ
REST APIのURLは、動詞(アクション)ではなく名詞(リソース)を含むべきです。HTTPメソッドが動詞を提供します。この原則により、一貫性があり、スケーラブルで、保守しやすいAPIが作成されます。
以前のSwagger Petstoreは、/pet/findByStatusのようなエンドポイントでこの原則に違反していました。Modern PetstoreAPIは、全体を通じてリソース指向のURLを使用することでこれを修正しています:/pets?status=AVAILABLE。
主なポイント:
- URLに名詞を使用する:
/pets、/orders、/users - HTTPメソッドを動詞として使用する:
GET、POST、PUT、DELETE - フィルタリングにクエリパラメータを使用する:
/pets?status=available - 複雑な操作にはサブリソースを使用する:
/orders/{id}/payment - ApidogでAPI設計をテストし、動詞の使用を早期に検出する
リソース指向URL設計の完全な例については、Modern PetstoreAPIドキュメントを参照してください。
よくある質問
REST URLで動詞を使用することはありますか?
めったにありません。操作が本当にリソースモデルに適合しない場合(/searchや/loginなど)、動詞が許容される場合があります。しかし、95%のケースでは、それをリソースとしてモデル化できます。
/loginと/logoutはどうですか?
これらは一般的な例外です。多くのAPIは/auth/loginと/auth/logoutを使用します。あるいは、それらをリソースとしてモデル化することもできます:POST /sessions(ログイン)とDELETE /sessions/{id}(ログアウト)。
複雑なクエリはどう処理しますか?
単純なフィルタリングにはクエリパラメータを使用します:/pets?status=available&species=dog。複雑なクエリには、QUERY HTTPメソッドまたは検索リソースを使用します:POST /pets/search。
操作がCRUDにマッピングできない場合はどうなりますか?
サブリソースとしてモデル化します。POST /processPaymentの代わりに、POST /orders/{id}/paymentを使用します。支払いは注文に関連するリソースです。
URLがリソース指向かどうかをテストするにはどうすればよいですか?
Apidogを使用してOpenAPI仕様をインポートし、URL内の動詞をチェックします。独自のAPI構造をModern PetstoreAPIと比較して参考にします。
/pets/searchと/pets?search=queryのどちらを使うべきですか?
どちらも許容されます。基本的な検索には/pets?search=queryの方がシンプルです。複数のパラメータを持つ複雑な検索には/pets/searchまたはQUERY /petsの方が適しています。
動詞ベースのURLから移行するにはどうすればよいですか?
APIバージョン管理(/v1/findPetsの代わりに/v2/pets)、非推奨警告の追加、およびクライアントに移行時間を与えることを行います。詳細については「移行戦略」セクションを参照してください。
Modern PetstoreAPIはURLに動詞を使用していますか?
Modern PetstoreAPIはURL内の動詞を避けています。検索、フィルタリング、認証などの操作は、リソースとしてモデル化されるか、クエリパラメータを使用します。REST APIドキュメントで例を確認してください。
