💡 Key Takeaways
- The Foundation: Understanding REST Beyond the Buzzword
- Principle 1: Resources Are Nouns, Not Verbs
- Principle 2: HTTP Methods Mean What They Mean
- Principle 3: Status Codes Are Your Communication Protocol
フィンテックユニコーンでの API アーキテクト主導の役割に就いて 3 年、私は投資家向けの製品デモ中に私たちのモバイルアプリが華々しくクラッシュするのを見ました。原因は何でしょう?「より多くのデータは常に良い」という発想から誰かが返す 47MB の JSON になった単一の API エンドポイントです。その恥ずかしい瞬間と、それが引き起こした 200 万ドルの資金調達遅延は、API デザインが「うまく機能する」というだけではなく、優雅で予測可能でスケール可能に機能することが重要であることを私に教えてくれました。
💡 重要な要点
- 基礎: バズワードを越えた REST の理解
- 原則 1: リソースは名詞であり、動詞ではない
- 原則 2: HTTP メソッドはその意味を持つ
- 原則 3: ステータス コードはあなたの通信プロトコルである
私はマーカス・チェンで、過去 12 年間にわたり、1 日 50 リクエストから 5000 万リクエストを処理する API の設計に従事してきました。素晴らしいエンジニアたちが、6 か月後には使い方を覚えられなくなるほど複雑な API を作成するのを見てきました。初心者の開発者が、ドキュメントがほとんど不要なほど直感的なインターフェースを作り上げるのも実際に見ています。違いは?フレームワーク、言語、およびアーキテクチャのトレンドを超えた基本的な原則へのコミットメントです。
そして、私は成功した API の構築を導いた 10 の原則を共有しています—それは本番インシデント、ユーザーフィードバック、数えきれないコードレビューを通じて鍛えられた原則です。これは理論的な理想ではなく、私のチームが何百時間も節約し、無数の統合の頭痛を防いできた戦闘テストされたガイドラインです。
基礎: バズワードを越えた REST の理解
具体的な原則に入る前に、不快な真実に着目しましょう: ほとんどの「REST API」は実際には RESTful ではありません。彼らは JSON 応答を持つ HTTP API であり、これは問題ありませんが、REST と呼ぶのは、両方とも車輪があるからと言って自転車をバイクと呼ぶようなものです。ロイ・フィールドングの元の REST 論文では、6 つの制約が概説されており、ほとんどの API は少なくとも 3 つのそれを破っています。
実際に重要なのはこれです: REST は API をリソースのコレクションとして扱い、それぞれが URL で識別され、標準の HTTP メソッドを通じて操作されるアーキテクチャスタイルです。このアプローチの美しさは予測可能性です。GET /users/123 を見ると、ドキュメントを読むことなく、その動作を知ることができます。POST /users を見ると、それが新しいユーザーを作成することを知っています。この一貫性が REST のスーパーパワーです。
私の経験では、REST の原則を真に理解しているチームは、チェックボックスとして扱っているチームよりも 40% 速く API を出荷します。なぜでしょう?REST はデザインの決定を導くメンタルモデルを提供します。このエンドポイントは新しいものとするべきか、クエリパラメータとするべきか?REST がそれに答えます。これが POST とするべきか、それとも PUT とするべきか?REST が教えてくれます。原則は制約ではなく、保護バリアです—メンテナブルでスケーラブルな API への道を維持するためのものです。
私はキャリアの中で 200 以上の API デザインをレビューしてきましたが、うまく成長したものはすべて 1 つの特性を共有しています: REST のリソース指向の考え方を尊重していました。メンテナンスの悪夢となったものは?REST をフレームワークではなく提案として扱ったものです。あなたの API は、思っているよりも長く持続します—おそらく最小でも運用中の 5 年から 7 年です。その持続可能性を念頭に置いて設計してください。
原則 1: リソースは名詞であり、動詞ではない
この原則は現実の違反を見るまでは明白に見えるかもしれません。かつて私は、/getUser、/createOrder、/deleteProduct のようなエンドポイントを持つ API を引き継いだことがあります。すべての操作が URL の動詞になっていて、HTTP メソッドが冗長でした。この API には、23 のリソースベースのエンドポイントで行えたことを 127 のエンドポイントが行っていました。
ルールはこうです: あなたの URL は物 (リソース) を表し、HTTP メソッドはそれらの物に対するアクションを表すべきです。POST /createUser の代わりに、POST /users を使用してください。GET /getUserOrders の代わりに、GET /users/123/orders を使用してください。これは独善的ではなく、一貫したメンタルモデルを作成することに関するものです。
認知負荷を考慮してください。動詞ベースの URL では、開発者は恣意的なエンドポイント名を記憶しなければなりませんが、リソースベースの URL ではパターンに従います。私たちのフィンテックアプリでは、適切なリソース命名にリファクタリングすることで、新しい開発者のオンボーディング時間を 3 週間から 1.5 週間に短縮しました。API は自己文書化されるようになりました。
もちろん、例外はあります。CRUD 操作にきれいに当てはまらないアクション—例えば POST /payments/123/refund や POST /orders/456/cancel—は許容されます。これはコントローラースタイルのエンドポイントであり、代替案が不格好な場合には問題ありません。鍵は、それらを希少かつ一貫して使用することです。現在の API では、89% のエンドポイントが純粋なリソース操作であり、残りの 11% は明確に文書化されたコントローラーアクションです。
リソースを命名する際は、常に複数形の名詞を使用してください。/users ではなく /user、/orders ではなく /order。確かに GET /users/123 は単一のユーザーを返しますが、それは文法的に奇妙に感じられるかもしれませんが、一貫性が文法に勝ります。単数と複数で何時間も議論するチームを見てきましたが、複数形を選んで先に進んでください。
原則 2: HTTP メソッドはその意味を持つ
HTTP には豊富な語彙があります: GET、POST、PUT、PATCH、DELETE など。それぞれ特定の意味があり、それらの意味を尊重することで API の予測可能性とキャッシュ可能性が向上します。それにもかかわらず、POST がすべてを行う API を定期的に見かけます—作成、更新、削除、さらにはデータの取得も行います。これは、大工のすべての作業にハンマーを使うようなもので、他の道具を学びたくないからです。
| アプローチ | 応答サイズ | ネットワーク効率 | クライアントの複雑さ |
|---|---|---|---|
| すべてを返す | リクエストあたり 47MB 以上 | 不良 - 大きなオーバーヘッド | 低 - だが浪費的 |
| ページングのみ | 可変、制御されていない | 中程度 - まだオーバーフェッチ | 低 - 簡単な実装 |
| フィールドフィルタリング | クライアントが制御 | 良好 - 必要なものを取得 | 中程度 - クエリパラメータが必要 |
| GraphQL の代替 | 正確に制御 | 優れた - オーバーフェッチなし | 高 - 学習曲線 |
| スマートデフォルト + 拡張 | 最適化されたベースライン | 優れた - バランスのとれたアプローチ | 低 - ほとんどの場合直感的 |
GET リクエストは安全であり、冪等性を持たなければなりません。安全とは、それらがサーバーの状態を変更しないことを意味します。冪等性とは、複数回呼び出しても同じ結果が得られることを意味します。これは学問的なことではなく、キャッシュを可能にし、リード重視の API ではサーバーの負荷を 60-80% 減少させることができます。ユーザープロフィール API の GET セマンティクスと HTTP キャッシュを正しく実装することで、サーバーコストが月に $4,200 減少しました。
POST は新しいリソースを作成します。これは安全でも冪等でもなく、2 回呼び出すと 2 つのリソースが作成されます。PUT はリソース全体を置き換え、冪等です—10 回呼び出すと、1 回呼び出すのと同じ効果が得られます。PATCH はリソースを部分的に更新し、冪等性を持つべきです。DELETE はリソースを削除し、冪等です。これらの違いはクライアントの再試行ロジック、キャッシング戦略、および API ゲートウェイの構成に重要です。
私たちの決済処理 API からの実際の例です。最初はすべてに POST を使用していましたが、決済状況の確認も含まれていました。ネットワークの問題によりクライアントがリクエストを再試行した際、重複した決済記録が作成されました。ステータス確認のために GET を使用し、POST リクエストの適切な冪等性キーを実装した後、重複決済は取引の 2.3% から 0.01% に減少しました。これは実際にかかったお金が節約され、顧客の信頼が維持されたことを意味します。
よくある質問の一つ: PUT と PATCH のどちらを使うべきですか?クライアントがリソースの完全な表現を送信する場合は PUT を使用します。クライアントが変更するフィールドのみを送信する場合は PATCH を使用します。実際には、クライアントはほとんどの場合すべてのフィールドを送信したくないため、PATCH の方が適切です。私たちの分析によれば、更新操作の 94% が PATCH を使用しており、ペイロードサイズを平均 73% 削減することでモバイルアプリもより効率的になりました。
原則 3: ステータス コードはあなたの通信プロトコルである
HTTP ステータス コードは通信のための標準化された言語です。