RESTful API:原則、デザイン、とベストプラクティス
Min-jun Kim
Dev Intern · Leapcell

RESTful API(Representational State Transfer API)は、ネットワークアプリケーション間のインタラクションに使用されるネットワークインターフェース設計スタイルです。RESTは、標準やプロトコルではなく、一連のアーキテクチャ原則と制約です。Webサービスが「RESTful」である場合、RESTの原則に従い、効率的で信頼性が高く、スケーラブルなネットワークサービスを提供します。
RESTfulサービスでは、各リクエストには、リクエストを処理するために必要なすべての情報が含まれている必要があります。サーバーは、クライアントリクエストに関する状態情報を保持してはなりません。
RESTfulアーキテクチャは、それぞれが特定の機能を実行する複数のレイヤーで構成される場合があります。この構造により、より複雑で強力なアプリケーションの開発が可能になります。
URI設計
RESTful API設計では、URL(Uniform Resource Locators)は通常、リソース(オブジェクト)を表し、HTTPメソッド(GET、POST、PUT、DELETEなど)はこれらのリソースに対する操作(動詞)を表します。この設計スタイルは、アクションではなく、リソースの状態と表現を重視します。
動詞 + オブジェクト
RESTful APIの動詞は通常、CRUD操作に対応する5つのHTTPメソッドです。
- GET: 読み取り
- POST: 作成
- PUT: 更新
- PATCH: 更新(通常は部分的な更新)
- DELETE: 削除
HTTP仕様によれば、動詞は常に大文字で記述する必要があります。
オブジェクトは名詞でなければならない
APIを設計する場合、URL(Uniform Resource Locator)は通常、HTTP動詞のオブジェクトとして機能するリソースを表します。RESTful設計の原則によれば、URLはアクションではなくリソース自体を表すため、動詞ではなく名詞である必要があります。URLは、「リソース」コレクションまたは単一インスタンスを表し、アクションを表すものではありません。
不適切な例:
/getAllCars
/createNewCar
/deleteAllRedCars
これらのURLには、動詞(get、create、deleteなど)が含まれており、リソース自体ではなくアクションを記述しています。この設計は、RESTfulセマンティック標準に準拠していません。
正しいアプローチ:
URLは、操作ではなくリソースの記述に焦点を当てる必要があります。以下は、準拠したURL設計の例です。
/users
: ユーザーのコレクションを表します/users/123
: 特定のID(123)を持つ単一のユーザーを表します
上記の例では、/users
と/users/123
はどちらも名詞であり、それぞれユーザーのコレクションと特定のユーザーリソースを表しています。このようなURL設計により、APIは理解しやすくなり、RESTfulリソース指向の原則に沿ったものになります。
この命名規則に従うことで、APIパスが明確で、一貫性があり、理解しやすく、保守しやすいものになります。
複数形のURL
URLで複数形を使用することは、通常、一貫性と明確さのために推奨されます。これらは通常、リソースのコレクションを表します。
URLがリソースのコレクションを指す場合は、複数名詞を使用します。たとえば、すべてのユーザーのコレクションを表すには、/user
の代わりに/users
を使用します。
単一のリソースを指す場合でも、複数形を使用することをお勧めします。たとえば、/users/123
はID 123のユーザーを表します。このアプローチは、URLの一貫性を維持します。
リソースに階層関係がある場合、URLはこの構造を反映する必要があります。たとえば、/users/123/posts
は、ユーザー123の投稿のコレクションを表すことができます。
深くネストされたURLの回避
一般的なシナリオは、リソースが複数レベルの分類を必要とする場合で、特定の著者の記事の特定のカテゴリを取得するなど、深くネストされたURLにつながります。
GET /authors/12/categories/2
このようなURLは拡張が難しく、セマンティクスが不明確で、理解するために余分な労力が必要になることがよくあります。より良いアプローチは、最上位レベルを超えてクエリパラメータを使用することです。
GET /authors/12?categories=2
別の例は、公開された記事のクエリです。次のようにURLを設計するかもしれません。
GET /articles/published
ただし、クエリパラメータを使用する方が明らかに良いアプローチです。
GET /articles?published=true
ステータスコード
ステータスコードは正確でなければならない
すべてのクライアントリクエストに対して、サーバーはHTTPステータスコードとデータで応答する必要があります。
HTTPステータスコードは、5つのカテゴリに分類される3桁の数字です。
- 1xx: 情報
- 2xx: 成功
- 3xx: リダイレクト
- 4xx: クライアントエラー
- 5xx: サーバーエラー
これらの5つのカテゴリには、考えられるほとんどの状況をカバーする100を超えるステータスコードが含まれています。各ステータスコードには標準(または慣習的に受け入れられている)意味があり、クライアントはステータスコードを確認するだけで何が起こったかを判断できます。したがって、サーバーは可能な限り最も正確なステータスコードを返す必要があります。
APIは1xxステータスコードを必要としません。以下は、他の4つのカテゴリの説明です。
2xxステータスコード
異なるHTTPリクエストメソッドは、リクエストの結果を示すために対応するステータスコードを返す必要があります。200 OKは一般的な成功応答ですが、メソッドに応じてより正確なステータスコードを使用する必要があります。
- GET: 200 OK – リクエストは成功し、リソースが返されます。
- POST: 201 Created – 新しいリソースが正常に作成され、応答には通常、リソースのURIが含まれています。
- PUT: 200 OK または 204 No Content – リソースの完全な更新に使用されます。コンテンツが返される場合は200を使用し、そうでない場合は204を使用します。
- PATCH: 200 OK または 204 No Content – PUTと同様に、部分的な更新に使用されます。204は、コンテンツが返されないことを示します。
- DELETE: 204 No Content – 通常、応答にコンテンツを含めずに、リソースが正常に削除されたことを示します。
- 202 Accepted – リクエストは承認されたが、まだ処理されていません。非同期操作に役立ちます。
- 206 Partial Content – 部分的な応答を示します。クライアントがRangeヘッダーを使用して大きなファイルの一部をリクエストする場合によく使用されます。
3xxステータスコード
APIは通常、ブラウザーレベルのナビゲーションに最も関連するため、**301(恒久的リダイレクト)または302(一時的リダイレクト、307を含む)**を使用しません。APIは、代わりにアプリケーションレベルでそのようなシナリオを処理できます。
ただし、APIは別のURLを参照する303 See Otherを使用する場合があります。302および307と同様に、「一时的なリダイレクト」を意味しますが、303は特にPOST、PUT、DELETEリクエストに使用されます。302とは異なり、ブラウザーは303リダイレクトを自動的にフォローするのではなく、ユーザーが次のステップを決定できるようにします。
応答の例:
HTTP/1.1 303 See Other
Location: /api/orders/12345
4xxステータスコード
4xxステータスコードは、クライアントエラーを示します。一般的なものには、次のものがあります。
- 400 Bad Request – サーバーはクライアントのリクエストを理解しておらず、処理しません。
- 401 Unauthorized – ユーザーが認証資格情報を提供していないか、認証に失敗しました。
- 403 Forbidden – ユーザーは正常に認証されましたが、リソースにアクセスするための権限がありません。
- 404 Not Found – リクエストされたリソースが存在しないか、利用できません。
- 405 Method Not Allowed – ユーザーは正常に認証されましたが、許可されていないHTTPメソッドを使用しています。
- 410 Gone – リクエストされたリソースは恒久的に削除されました。
- 415 Unsupported Media Type – リクエストされた形式はサポートされていません。たとえば、APIがJSONのみを返す場合、クライアントがXMLをリクエストすると、このステータスを返す必要があります。
- 422 Unprocessable Entity – クライアントが処理できない添付ファイルを提供したため、リクエストが失敗しました。
- 429 Too Many Requests – クライアントが許可されたリクエスト数を超えました。
5xxステータスコード
5xxステータスコードは、サーバーエラーを示します。APIは通常、内部サーバーの詳細をユーザーに公開しないため、一般的に使用されるステータスコードは2つだけです。
- 500 Internal Server Error – クライアントリクエストは有効でしたが、サーバーが処理中に予期しない問題が発生しました。
- 503 Service Unavailable – サーバーが一時的にリクエストを処理できません。メンテナンス期間中によく使用されます。
サーバーの応答
プレーンテキストを返さない
API応答はプレーンテキストではなく、構造化されたJSONオブジェクトである必要があります。これにより、標準形式が保証されます。サーバーのContent-Typeヘッダーはapplication/jsonに設定する必要があります。
クライアントは、リクエストにAcceptヘッダーを設定して、JSON応答を受け入れることも指定する必要があります。
GET /orders/2 HTTP/1.1
Accept: application/json
エラーに対して200ステータスコードを返さない
エラーが発生した場合でも常に200 OKを返し、応答本文にエラーの詳細を含めるのは、間違ったアプローチです。これにより、クライアントは応答本文を解析してリクエストが失敗したかどうかを判断する必要があり、ステータスコードの目的が損なわれます。
悪い例:
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "failure",
"data": {
"error": "リストに少なくとも2つのアイテムが必要です。"
}
}
この場合、リクエストは失敗しましたが、サーバーは依然として200 OKを返しました。クライアントは、応答本文の"status": "failure"
フィールドを確認してエラーを検出する必要があります。このアプローチはRESTfulではなく、エラー処理がより複雑になり、エラーが発生しやすくなります。
正しい例:
ステータスコードは、リクエストの結果を示す必要があります。エラーは適切なステータスコードを使用して伝え、応答本文には詳細情報を提供する必要があります。
たとえば、リクエストが無効な場合、サーバーは400 Bad Requestを返し、JSON形式でエラーの詳細を記述する必要があります。
HTTP/1.1 400 Bad Request
Content-Type: application/json
{
"error": "ペイロードが無効です。",
"detail": {
"surname": "このフィールドは必須です。"
}
}
ここでは、400は無効なリクエストであることを明確に示し、応答本文はクライアントが問題を理解するのに役立つ特定のエラーの詳細を提供します。
リンクの提供
RESTful APIでは、応答にリンクを含めるのが一般的な方法です。これは、**Hypermedia as the Engine of Application State(HATEOAS)**の原則に従っており、APIの発見可能性と自己記述性を高めます。
リンクを含める一般的な方法は2つあります。
HAL(Hypertext Application Language)の使用
HALは、リソース間の関係を表す一般的なハイパーメディア形式です。JSON応答で_linksフィールドを使用します。
{ "id": 1, "name": "Example", "_links": { "self": { "href": "http://api.example.com/resource/1" }, "related": { "href": "http://api.example.com/resource/2" } } }
JSONにリンクを直接埋め込む
{ "id": 1, "name": "Example", "links": { "self": "http://api.example.com/resource/1", "related": "http://api.example.com/resource/2" } }
コンテンツの返却ポリシー
RESTful API設計では、POSTリクエストは新しいリソースを作成するために使用されます。応答に新しく作成されたリソースを含めるかどうかは、実装のニーズによって異なります。一般的なアプローチは2つあります。
1. 作成されたリソースを返す
このアプローチでは、201 Createdステータスコードと、応答内の新しいリソースの完全な詳細が含まれます。また、リソースのURIを指すLocationヘッダーも含まれます。
HTTP/1.1 201 Created
Location: /resources/123
Content-Type: application/json
{
"id": 123,
"name": "New Resource"
}
2. コンテンツを返さない
代わりに、サーバーはLocationヘッダーを含む201 Createdまたは204 No Content応答のみを返し、リソースの詳細を省略することを選択できます。これにより、データ転送が最小限に抑えられ、クライアントが後でリソースを取得するかどうかを決定できます。
HTTP/1.1 201 Created
Location: /resources/123
結論
RESTful APIはHTTPプロトコルに従い、リソースの表現とステートレスなインタラクションを重視します。標準のHTTPメソッド(GET、POST、PUT、DELETE)と正確なステータスコードを使用することで、RESTfulアーキテクチャは、ネットワークアプリケーションを構築するためのシンプルで効率的、かつ保守が容易な方法を提供します。このアプローチは、Webサービスのスケーラビリティ、柔軟性、および保守性を高めます。
バックエンドプロジェクトをホストするための最高の選択肢であるLeapcellをご紹介します。
Leapcellは、Webホスティング、非同期タスク、およびRedis向けの次世代サーバーレスプラットフォームです。
マルチ言語サポート
- Node.js、Python、Go、またはRustで開発します。
無制限のプロジェクトを無料でデプロイ
- 使用量に対してのみ支払い - リクエストも課金もありません。
比類のないコスト効率
- アイドル料金なしの従量課金制。
- 例:$25は、平均応答時間60msで694万件のリクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOpsの統合。
- 実用的な洞察のためのリアルタイムメトリックとロギング。
簡単なスケーラビリティと高性能
- 高い同時実行を簡単に処理するための自動スケーリング。
- 運用上のオーバーヘッドはゼロ - 構築に集中するだけです。
詳細については、ドキュメントをご覧ください。
Xでフォローしてください:@LeapcellHQ