コールバック
OpenAPI 3 の仕様では、**コールバック**を定義できます。これは、特定のイベントに応答してサービスが他のサービスに送信する非同期のアウトオブバンドのリクエストです。これにより、API がクライアントに提供するワークフローを改善できます。コールバックの典型的な例は、サブスクリプション機能です。ユーザーはサービスの特定のイベントを購読し、そのイベントが発生したときに通知を受け取ります。たとえば、電子ショップは購入ごとにマネージャーに通知を送信できます。これらの通知は「アウトオブバンド」であり、訪問者が作業する接続とは異なる接続を介して行われ、通常の要求-応答フロー外であるため非同期です。OpenAPI 3 では、「サブスクリプション」操作の形式、コールバックメッセージの形式、およびこれらのメッセージへの期待される応答を定義できます。この説明は、異なるサーバー間の通信を簡素化し、API での Webhook の使用を標準化するのに役立ちます。
コールバックの例
シンプルな Webhook 通知のコールバック定義を作成しましょう。API がリクエストボディにコールバック URL を期待する POST /subscribe
操作を提供すると仮定します。
1POST /subscribe2Host: my.example.com3Content-Type: application/json4
5{6 "callbackUrl": "https://myserver.com/send/callback/here"7}
API はサブスクリプションを承認します —
1HTTP/1.1 201 Created
— その後、特定のイベントに関する通知を送信します。
1POST /send/callback/here2Host: myserver.com3Content-Type: application/json4
5{6 "message": "Something happened"7}
次に、/subscribe
操作を定義しましょう。
1openapi: 3.0.42info:3 version: 0.0.04 title: test5
6paths:7 /subscribe:8 post:9 summary: Subscribe to a webhook10 requestBody:11 required: true12 content:13 application/json:14 schema:15 type: object16 properties:17 callbackUrl: # Callback URL18 type: string19 format: uri20 example: https://myserver.com/send/callback/here21 required:22 - callbackUrl23 responses:24 "201":25 description: Webhook created
次に、この操作にコールバックキーワードを追加してコールバックを定義します。
1paths:2 /subscribe:3 post:4 summary: Subscribe to a webhook5 requestBody: …6 callbacks: # Callback definition7 myEvent: # Event name8 "{$request.body#/callbackUrl}": # The callback URL,9 # Refers to the passed URL10 post:11 requestBody: # Contents of the callback message12 required: true13 content:14 application/json:15 schema:16 type: object17 properties:18 message:19 type: string20 example: Some event happened21 required:22 - message23 responses: # Expected responses to the callback message24 "200":25 description: Your server returns this code if it accepts the callback
この定義を一行ずつ見ていきましょう。
callbacks
は、関連する操作 (たとえば、post
、put
など) の中に定義されます (パス自体の下ではありません)。この例では、/subscribe
パスのpost
メソッドの下にあります。
1paths:2 /subscribe:3 post:4 …5 callbacks:6 …
これは、この操作が機能している場合にのみ API がコールバックを送信するという意味ではありません。API は、サービスビジネスロジックが必要なときにコールバックリクエストを送信します。キーワードの階層は、/subscribe
操作のパラメーターを使用してコールバックリクエストを設定できるだけです (下記参照)。
callbacks
の内部で、1 つ以上のコールバックメッセージを定義します。この例では、1 つのメッセージのみです。複数のコールバックの例は後述します。各コールバックの定義は、イベント名 (_myEvent_
の例では) で始まります。
1callbacks:2 myEvent: # Event name
- イベント名の下に、サービスがコールバックメッセージを送信する URL を定義します。この例では、URL は
{$request.body#/callbackUrl}
式を使用して指定されています。
1callbacks:2 myEvent:3 "{$request.body#/callbackUrl}": # The callback URL, refers to the URL passed in the request body
この式は、コールバックURLが /subscribe
操作のパラメーターに基づいて決定されることを示しています。これらの式については、後ほど詳しく説明します。
- URL の下には、コールバックメッセージのメソッドを指定し、メッセージ形式と期待される応答を定義します。これらの定義は、通常の要求と応答の定義に似ています。
1callbacks:2 myEvent:3 "{$request.body#/callbackUrl}":4 post: # Method5 requestBody: # Contents of the callback message6 …7 responses: # Expected responses8 …
コールバックを定義するときは、API の仕様を定義していることに注意してください。コールバック機能の実際の実装は、サーバーコードで行われます。
ランタイム式を使用してリクエストフィールドを参照する
ご覧のとおり、この例では {$request.body#/callbackUrl}
式を使用しています。これは、POST /subscribe
リクエストのどのデータがコールバックで使用されるかを設定するランタイム式です。*ランタイム*とは、API エンドポイントとは異なり、この URL は事前にわかっておらず、API クライアントによって提供されたデータに基づいて実行時に評価されることを意味します。この値はクライアントによって異なります。たとえば、POST /subscribe
リクエストは次のようになります。
1POST /subscribe?p1=query-param-value HTTP/1.12Host: my.example.com3Content-Type: application/json4Content-Length: 1875
6{7 "callbackUrl" : "http://my.client.com/callback"8}9
10201 Created11Location: http://my.example.com?id=123
そのデータを参照するには、以下の式を使用できます。
式 | 例 | 説明 |
---|---|---|
{$url} | /subscribe | 親操作の URL。 |
{$method} | POST | コールバックリクエストのメソッド。 |
{$request.path.eventType} | myEvent | イベント名。 |
{$request.query.param-name} | query-param-value ( p1 クエリパラメータ) | 指定されたクエリパラメータの値。 |
{$request.header.header-name} | application/json (Content-Type ヘッダー) | 「サブスクリプション」リクエストの指定されたヘッダー。 |
{$request.body#/field-name} | callbackUrl | リクエストボディ内のフィールド。フィールドが配列の場合は、{$request.body#/arrayField/2} のような構文を使用します。 |
{$response.header.header-name} | http://my.example.com?id=123 (Location ヘッダー) | 指定されたレスポンスヘッダーの値 (「サブスクリプション」リクエストへのレスポンス)。 |
コールバック定義では、ランタイム式と静的データを組み合わせることができます。たとえば、次のようにコールバック URL を定義できます。
1{$request.body#callbackUrl}/data:2– or –3{$request.body#/callbackUrl}/{$request.query.eventType}:
式を使用してクエリパラメータを指定できます。
1{$request.body#/callbackUrl}/data?p1={$request.query.eventType}
文字列にランタイム式と静的テキストの両方が含まれている場合は、ランタイム式を中括弧で囲む必要があります。文字列全体がランタイム式である場合は、中括弧を省略できます。
複数のコールバック
上記のように、1つの「サブスクリプション」操作を使用して複数のコールバックを定義できます。
1/subscribe:2 post:3 requestBody:4 content:5 application/json:6 schema:7 type: object8 properties:9 inProgressUrl:10 type: string11 failedUrl:12 type: string13 successUrl:14 type: string15 responses:16 "200":17 description: OK18 callbacks:19 inProgress:20 "{$request.body#/inProgressUrl}":21 post:22 requestBody:23 $ref: "#/components/requestBodies/callbackMessage1"24 responses:25 "200":26 description: OK27 "{$request.body#/failedUrl}":28 post:29 requestBody:30 $ref: "#/components/requestBodies/callbackMessage2"31 responses:32 "200":33 description: OK34 "{$request.body#/successUrl}":35 post:36 requestBody:37 $ref: "#/components/requestBodies/callbackMessage3"38 responses:39 "200":40 description: OK
コールバックの解除
サブスクライブ解除メカニズムの実装方法はあなた次第です。たとえば、受信サーバーはコールバックメッセージに応答して特定のコードを返し、コールバックに興味がないことを示すことができます。この場合、クライアントはコールバックリクエストに応答してのみサブスクライブ解除できます。クライアントがいつでもサブスクライブ解除できるように、API は特別な「サブスクライブ解除」操作を提供できます。これはかなり一般的なアプローチです。この場合、サービスは各サブスクライバーの ID またはトークンを生成し、「サブスクリプション」リクエストへの応答としてこの ID またはトークンを返すことができます。サブスクライブ解除するには、クライアントはこの ID を「サブスクライブ解除」操作に渡して、削除するサブスクライバーを指定できます。以下の例は、この動作を仕様で定義する方法を示しています。
1paths:2/subscribe:3 description: Add a subscriber4 post:5 parameters:6 - name: callbackUrl7 in: query8 required: true9 schema:10 type: string11 format: uri12 - name: event13 in: query14 required: true15 schema:16 type: string17 responses:18 '201':19 description: Added20 content:21 application/json:22 type: object23 properties:24 subscriberId:25 type: string26 example: AAA-123-BBB-45627 links: # Link the returned id with the unsubscribe operation28 unsubscribeOp:29 operationId: unsubscribeOperation30 parameters:31 Id: $response.body#/subscriberId32 callbacks:33 myEvent:34 '{$request.query.callbackUrl}?event={$request.query.event}':35 post:36 requestBody:37 content:38 application/json:39 example:40 message: Some event41 responses:42 '200':43 description: OK44
45/unsubscribe:46 post:47 operationId: unsubscribeOperation48 parameters:49 - name: Id50 in: query51 required: true52 schema:53 type: string
お探しのものが見つかりませんでしたか? コミュニティに質問する
間違いを見つけましたか? お知らせください