変更要約: 初版
2.4APIスタイルの比較
リソース指向でステートレスなREST(URLで表したリソースをHTTPメソッドで操作)と、手続き(関数)の呼び出しとして設計するRPCの違い、そして呼び出し側が応答を待つ同期(synchronous)と、要求を受理だけして後で結果を返す非同期(asynchronous)(202 Accepted+ポーリング/コールバック)の使い分けを、「この要件・この処理時間にはどのスタイルが適切か」という設計判断として学びます。
「APIを使う」と一口に言っても、その設計スタイルは一様ではありません。リソースを名詞で表すRESTと操作を動詞(関数)で表すRPCでは、URLやメソッドの読み方が変わります。また、その場で結果を待つ同期と、受理だけして後で結果を得る非同期では、クライアントの作り方がまったく異なります。この節では、目の前のAPI応答(例:202 Accepted)や要件(処理が数分かかる等)から、どのスタイルで設計/利用すべきかを判断できるようにします。
2.4.1RESTとRPC
- REST=リソース指向。URLが「モノ」(リソース)を表し、それに対する操作をHTTPメソッドで表現する。例:
GET /devices/42(取得)・DELETE /devices/42(削除)。ステートレス(各リクエストが自己完結し、サーバは前の呼び出しの状態を保持しない)で、標準的なHTTPの仕組み(メソッド・ステータス・キャッシュ)に素直に乗るのが強み。 - RPC(Remote Procedure Call)=手続き指向。URLやメッセージが「関数の呼び出し」を表し、たいてい
POST一本で{"method":"rebootDevice","params":{"id":42}}のように動詞(操作名)+引数を送る。gRPCやJSON-RPCが例。「リソースのCRUD」に馴染まない複雑な操作を1つのアクションとして呼びたいときに向く。 - 見分け方:URLが名詞(リソース)中心でメソッドが操作ならREST寄り(
GET /users/5)、URLやボディが動詞(関数名)中心ならRPC寄り(POST /getUser{"id":5})。試験では「この呼び出しはどちらのスタイルか」「REST的に設計するとURL/メソッドはどうなるか」を問われる。
2.4.2同期と非同期
- 同期(synchronous)=リクエストを送ったら、処理が終わって結果が返るまでその場で待つモデル。実装が単純で、
GETのような即座に終わる取得に向く。ただし処理に長時間かかると、その間クライアントは待たされ、コネクションのタイムアウトのリスクもある。 - 非同期(asynchronous)=サーバは要求を受理だけしてすぐ
202 Acceptedを返し、実処理は裏で進める。クライアントは後でジョブ状態をポーリング(GET /jobs/{id})するか、Webhook/コールバックで完了通知を受ける。数分かかる一括処理・重い集計・多数機器への一斉操作など、待たせられない/待てない処理に向く。
「REST=リソース指向・ステートレス・URL(名詞)+HTTPメソッド」「RPC=手続き指向・関数呼び出し(動詞+引数、多くPOST)」「同期=結果が返るまで待つ/非同期=202 Acceptedで受理し後でポーリング/コールバックで結果取得」が頻出です。設問は「この応答(202)や要件(長時間処理)にはどのモデルか」「REST的URLはどれか」で判断しましょう。
あなたは「1000台のネットワーク機器へ設定変更を一斉適用する」APIをクライアントから利用します。試しにPOST /config/applyを同期的に呼んだところ、処理に数分かかり、クライアントは応答を待ち続けた末にHTTPのタイムアウトで接続が切れ、結果が受け取れませんでした。ここで「タイムアウト値を延ばせば同期のままいける」と考えるのは筋が悪い判断です——ネットワーク経路上のプロキシやLBにも独自のタイムアウトがあり、長時間の同期呼び出しは本質的に脆いからです。docsを読むと、このエンドポイントは非同期設計で、呼ぶと即座に202 Acceptedとともにボディで{"jobId":"abc123","status":"pending"}を返し、ジョブの完了は別途GET /jobs/abc123で確認する、と書かれていました。つまり正しい利用法は、(1)POSTで処理を投入し202とjobIdを受け取る、(2)GET /jobs/abc123を適度な間隔で(かつレート制限に配慮して指数バックオフで)ポーリングしてstatusがcompleted/failedになるのを待つ、あるいはWebhookが使えるなら完了通知を受ける、という流れです。この設計なら、長時間処理でもクライアントは接続を占有し続けずに済みます。スタイルの観点では、この操作は「リソースのCRUD」というより「一斉適用という手続き」に近く、RPC的な色もありますが、Ciscoのプラットフォーム系APIの多くはRESTの枠内でジョブをリソース化(/jobs/{id})して非同期を表現します。ここで学ぶべきは、処理時間と要件からスタイル(REST/RPC)と呼び出しモデル(同期/非同期)を選ぶ——短く即答できるものは同期のREST、長時間・一括・待てないものは非同期(202+ジョブポーリング/コールバック)——という設計判断であり、「同期でタイムアウトを延ばして耐える」は正攻法ではない、ということです。
| 観点 | REST / 同期 | RPC / 非同期 |
|---|---|---|
| 設計の中心 | REST=リソース(名詞)+HTTPメソッド | RPC=手続き(動詞・関数呼び出し) |
| 状態 | ステートレス(各リクエスト自己完結) | 操作を1アクションとして呼ぶ |
| 待ち方 | 同期=結果が返るまで待つ(短時間向き) | 非同期=`202`で受理し後で結果取得(長時間向き) |
| 完了の知り方 | その場の応答で完了 | ジョブをポーリング/Webhookで通知 |
ひっかけ: 「長時間かかる処理でも、クライアントのタイムアウト値を延ばせば同期呼び出しで問題ない」は誤りです——経路上のプロキシ/LBのタイムアウトや接続占有の問題があり、長時間処理は非同期(202 Accepted+ジョブのポーリング/コールバック)で扱うのが定石です。また「POST /getDevice のように動詞をURLに置くのがRESTだ」も誤り=それはRPC的で、RESTはリソース(名詞)URL+HTTPメソッド(GET /devices/{id})で表します。
2.4.3この節のまとめ
- RESTはリソース(名詞URL)+HTTPメソッドでステートレス、RPCは手続き(動詞・関数呼び出し)中心。URLが名詞かの動詞かで見分ける
- 同期は結果が返るまで待つ(短時間の取得向き)、非同期は
202 Acceptedで受理し後でポーリング/コールバックで結果取得(長時間・一括向き) - 長時間処理は同期でタイムアウトを延ばすのではなく非同期+ジョブポーリング/Webhookで設計する
進捗の記録にはログインが必要です。
理解度チェック
(軽い確認用)Q1. 1000台の機器へ設定を一斉適用するAPIを `POST /config/apply` で同期的に呼んだところ、処理に数分かかりHTTP接続がタイムアウトして結果を受け取れなかった。docsには「呼び出すと `202 Accepted` と `jobId` を返し、完了は `GET /jobs/{id}` で確認する」とある。最も適切な利用方法はどれか。
Q2. あるAPIは、単一デバイスの情報取得を `POST /getDeviceInfo` にボディ `{"deviceId":42}` を送る形で提供している。これをRESTの原則に沿って再設計する場合、最も適切なエンドポイント/メソッドはどれか。
Q3. クライアントがジョブ投入APIを呼ぶと、即座に `202 Accepted` が返り、ボディは `{"jobId":"j-99","status":"pending"}` だった。この応答が示す呼び出しモデルと、クライアントが次にすべきこととして最も適切なものはどれか。

