HTTP トリガーは、関数を HTTP(S) エンドポイント (関数 URL と呼ばれます) として公開します。クライアントが関数 URL を呼び出すと、Function Compute は HTTP リクエストをイベントオブジェクトに変換し、関数ハンドラに渡します。関数が値を返すと、Function Compute はその出力を HTTP レスポンスにマッピングし、クライアントに送信します。
このトピックでは、ビルトインランタイムにおける HTTP トリガーの動作について説明します。カスタムランタイムについては、「Web 関数」をご参照ください。
Function Compute 3.0 では、ビルトインランタイムにおける HTTP トリガーの動作が Function Compute 2.0 とは大きく異なります。詳細については、「仕組み」をご参照ください。カスタムランタイムおよびカスタムコンテナランタイムの場合、動作は Function Compute 2.0 と同じです。
仕組み
クライアントがご利用の関数 URL を呼び出すと、次の処理が行われます。
-
Function Compute が HTTP リクエストをイベントオブジェクト (
event) にマッピングします。 -
イベントオブジェクトが関数ハンドラに渡されます。
-
関数が値を返すと、Function Compute はその出力を HTTP レスポンスにマッピングし、クライアントに返送します。
リクエスト構造体
フォーマット
Function Compute は、受信した HTTP リクエストを次の構造を持つイベントオブジェクトにマッピングします。
{
"version": "v1",
"rawPath": "/example",
"body": "Hello FC!",
"isBase64Encoded": false,
"headers": {
"header1": "value1",
"header2": "value1,value2"
},
"queryParameters": {
"parameter1": "value1",
"parameter2": "value1,value2"
},
"requestContext": {
"accountId": "123456*********",
"domainName": "<http-trigger-id>.<region-id>.fcapp.run",
"domainPrefix": "<http-trigger-id>",
"http": {
"method": "GET",
"path": "/example",
"protocol": "HTTP/1.1",
"sourceIp": "11.11.11.**",
"userAgent": "PostmanRuntime/7.32.3"
},
"requestId": "1-64f6cd87-*************",
"time": "2023-09-05T06:41:11Z",
"timeEpoch": "1693896071895"
}
}
パラメーター
| パラメーター | 説明 | 例 |
|---|---|---|
version |
ペイロードフォーマットのバージョン。サポートされている値は v1 のみです。 |
v1 |
rawPath |
URL エンコードされたリクエストパス。リクエスト URL が https://{url-id}.{region}.fcapp.run/example の場合、この値は /example です。デコードされたパスについては、requestContext.http.path をご参照ください。 |
/example |
body |
リクエストボディ。バイナリデータは Base64 エンコードされます。 | Hello FC! |
isBase64Encoded |
リクエストボディが Base64 エンコードされているかどうか。有効な値:true、false。 |
false |
headers |
キーと値のペアとしてのリクエストヘッダー。キーに複数の値がある場合、カンマで区切られます。Function Compute 3.0 では、各ヘッダーキーの最初の文字が大文字に変換 (正規化) されます。詳細については、「HTTP トリガーを使用して関数を呼び出すと、なぜヘッダーキーの最初の文字が大文字になるのですか? | {"Header1": "value1", "Header2": "value1,value2"} |
queryParameters |
JSON オブジェクトとしてのクエリパラメーター。URL が https://{url-id}.{region}.fcapp.run/example?key1=value1 の場合、この値は {"key1": "value1"} です。同じキーに複数の値がある場合、カンマで区切られます。 |
{"parameter1": "value1", "parameter2": "value1,value2"} |
requestContext |
リクエスト ID、タイムスタンプ、呼び出し元情報などの追加のリクエストメタデータ。 | — |
requestContext.accountId |
関数を所有する Alibaba Cloud アカウントの ID。 | 123456********* |
requestContext.domainName |
HTTP トリガーのドメイン名。 | <http-trigger-id>.<region-id>.fcapp.run |
requestContext.domainPrefix |
HTTP トリガーのドメインプレフィックス。 | <http-trigger-id> |
requestContext.http |
HTTP リクエストに関する詳細情報。 | — |
requestContext.http.method |
HTTP メソッド。有効な値:GET、POST、PUT、HEAD、OPTIONS、PATCH、DELETE。 |
GET |
requestContext.http.path |
デコードされたリクエストパス。リクエスト URL が https://{url-id}.{region}.fcapp.run/example?name=Jane の場合、この値は /example です。 |
/example |
requestContext.http.protocol |
リクエストプロトコル。 | HTTP/1.1 |
requestContext.http.sourceIp |
直接 TCP 接続のピア IP (RemoteAddr)。下記の注記をご参照ください。 | 11.11.XX.XX |
requestContext.http.userAgent |
user-agent リクエストヘッダーの値。 |
PostmanRuntime/7.32.3 |
requestContext.requestId |
呼び出しログを追跡するためのリクエスト ID。 | 1-64f6cd87-************* |
requestContext.time |
ISO 8601 形式のリクエストタイムスタンプ。 | 2023-09-05T06:41:11Z |
requestContext.timeEpoch |
UNIX 時間 (ミリ秒) のリクエストタイムスタンプ。 | 1693896071895 |
sourceIp は直接 TCP 接続のピア IP であり、必ずしも元のクライアント IP ではありません。リクエストがプロキシによって転送されていない場合、sourceIp はクライアントの IP です。リクエストが 1 つ以上のプロキシを通過する場合、sourceIp は最後のプロキシの IP です。リクエストがプロキシを通過する場合に元のクライアント IP を取得するには、X-Forwarded-For ヘッダーを読み取ります。詳細については、「HTTP トリガーがビルトインランタイムを使用する関数を呼び出す際に、クライアントの元の IP アドレスを取得するにはどうすればよいですか?」をご参照ください。
マッピングロジック
Function Compute は、HTTP リクエストを次のようにイベントオブジェクトにマッピングします。
-
HTTP リクエストヘッダー →
event.headers -
HTTP クエリパラメーター →
event.queryParameters -
リクエストコンテキスト (リクエスト ID、タイムスタンプ、呼び出し元 ID) →
event.requestContext -
POST リクエストボディ →
event.body
Base64 エンコーディング
Function Compute は Content-Type ヘッダーをチェックして、リクエストボディを Base64 エンコードするかどうかを決定します。
Content-Type |
isBase64Encoded |
ボディの処理 |
|---|---|---|
text/* |
false |
そのまま渡される |
application/json |
false |
そのまま渡される |
application/ld+json |
false |
そのまま渡される |
application/xhtml+xml |
false |
そのまま渡される |
application/xml |
false |
そのまま渡される |
application/atom+xml |
false |
そのまま渡される |
application/javascript |
false |
そのまま渡される |
| その他の値 | true |
関数に渡す前に Base64 エンコードされる |
リクエストマッピングの例
GET
| HTTP リクエスト | イベントオブジェクト |
|---|---|
GET /?parameter1=value1¶meter2=value2 HTTP/1.1 |
{"version":"v1","rawPath":"/","headers":{"Accept":"*/*","User-Agent":"CurlHttpClient"},"queryParameters":{"parameter1":"value1","parameter2":"value2"},"body":"","isBase64Encoded":true,"requestContext":{"accountId":"1327**********","domainName":"example.cn-hangzhou.fcapp.run","domainPrefix":"example","requestId":"1-67aee50c-****-**********","time":"2025-02-14T06:39:08Z","timeEpoch":"1739515148145","http":{"method":"GET","path":"/","protocol":"HTTP/1.1","sourceIp":"40.XX.XX.XX","userAgent":"CurlHttpClient"}}} |
CLI からこのリクエストを送信するには、次のコマンドを実行します (https://example.cn-hangzhou.fcapp.run をご利用の関数 URL に置き換えてください)。
curl -v "https://example.cn-hangzhou.fcapp.run?parameter1=value1¶meter2=value2"
POST
| HTTP リクエスト | イベントオブジェクト |
|---|---|
|
{"version":"v1","rawPath":"/","headers":{"Accept":"*/*","Content-Length":"20","Content-Type":"application/json","User-Agent":"curl/8.7.1"},"queryParameters":{},"body":"{\"message\": \"Hello\"}","isBase64Encoded":false,"requestContext":{"accountId":"1327**********","domainName":"example.cn-hangzhou.fcapp.run","domainPrefix":"example","requestId":"1-67aee50c-****-**********","time":"2025-02-14T06:39:08Z","timeEpoch":"1739515148145","http":{"method":"POST","path":"/","protocol":"HTTP/1.1","sourceIp":"40.XX.XX.XX","userAgent":"CurlHttpClient"}}} |
CLI からこのリクエストを送信するには、次のコマンドを実行します (https://example.cn-hangzhou.fcapp.run をご利用の関数 URL に置き換えてください)。
curl -v -H "Content-Type: application/json" -d '{"message": "Hello"}' "https://example.cn-hangzhou.fcapp.run"
リクエストボディの Base64 エンコーディングを強制するには、Content-Typeをapplication/x-www-form-urlencodedに設定します。
レスポンス構造体
フォーマット
関数出力は、HTTP レスポンスにマッピングされる前に、レスポンス構造体に解析されます。
{
"statusCode": 200,
"headers": {
"Content-Type": "application/json",
"Custom-Header-1": "Custom Value"
},
"isBase64Encoded": false,
"body": "{\"message\":\"Hello FC!\"}"
}
マッピングロジック
Function Compute は、関数出力が statusCode フィールドを含む有効な JSON であるかどうかに基づいて、関数出力を HTTP レスポンスにマッピングします。
出力が statusCode を含む有効な JSON の場合:
| レスポンス構造体のフィールド | HTTP レスポンス |
|---|---|
statusCode |
ステータスコード |
headers["Content-Type"] |
Content-Type ヘッダー (存在しない場合はデフォルトで application/json) |
body |
レスポンスボディ |
isBase64Encoded |
送信前にボディを Base64 デコードするかどうか (存在しない場合はデフォルトで false) |
出力が statusCode を含まない有効な JSON、または JSON ではない場合:
Function Compute は次のデフォルト値を使用します。
| フィールド | デフォルト値 |
|---|---|
statusCode |
200 |
Content-Type |
application/json |
body |
関数出力 (そのまま) |
isBase64Encoded |
false |
レスポンスマッピングの例
以下の例は、関数出力が解析を経て最終的な HTTP レスポンスになるまでの流れを示しています。
文字列レスポンスの出力
| 関数出力 | 解析されたレスポンス構造体 | HTTP レスポンス (クライアントが受信) |
|---|---|---|
Hello World! |
{"statusCode":200,"body":"Hello World!","headers":{"content-type":"application/json"},"isBase64Encoded":false} |
|
JSON レスポンスの出力
| 関数出力 | 解析されたレスポンス構造体 | HTTP レスポンス (クライアントが受信) |
|---|---|---|
{"message": "Hello World!"} |
{"statusCode":200,"body":"{\"message\": \"Hello World!\"}","headers":{"content-type":"application/json"},"isBase64Encoded":false} |
|
カスタムレスポンスの出力
| 関数出力 | 解析されたレスポンス構造体 | HTTP レスポンス (クライアントが受信) |
|---|---|---|
{"statusCode":201,"headers":{"Content-Type":"application/json","My-Custom-Header":"Custom Value"},"body":{"message":"Hello, world!"},"isBase64Encoded":false} |
{"statusCode":201,"headers":{"Content-Type":"application/json","My-Custom-Header":"Custom Value"},"body":{"message":"Hello, world!"},"isBase64Encoded":false} |
|
Base64 デコーディング
関数が isBase64Encoded を true に設定した有効な JSON を返す場合、Function Compute は body を Base64 デコードしてから HTTP レスポンスボディにマッピングします。デコードに失敗した場合、Function Compute はエラーを報告せずに body の値を直接返します。
レスポンスヘッダー
Function Compute は、すべてのレスポンスに X-Fc-Request-Id ヘッダーを自動的に追加します。このヘッダーはリクエストを一意に識別し、ログの追跡やエラーの診断に役立ちます。X-Fc-Request-Id を除き、Function Compute はデフォルトで他のレスポンスヘッダーを追加しません。
X-Fc- プレフィックスを持つカスタムヘッダーはサポートされていません。以下のヘッダーは Function Compute によって予約されており、関数から返された場合は無視されます。
-
connection -
content-length -
date -
keep-alive -
server -
content-disposition
エラー処理
HTTP トリガーによる呼び出しと直接 API 呼び出しでは、関数エラーの処理方法が異なります。
| 呼び出しタイプ | エラー動作 | HTTP ステータスコード |
|---|---|---|
| 直接 API 呼び出し | エラーメッセージがレスポンスボディで返される | 200 |
| HTTP トリガー (関数 URL) | エラーメッセージは非表示。Internal Server Error が返される |
502 |
たとえば、Python の ModuleNotFoundError が発生した直接 API 呼び出しでは、次のエラー詳細が返されます。
{
"errorMessage": "Unable to import module 'index'",
"errorType": "ImportModuleError",
"stackTrace": [
"ModuleNotFoundError: No module named 'not_exist_module'"
]
}
HTTP トリガー経由で呼び出された関数でエラーが発生すると、クライアントは次のようなレスポンスを受信します。
HTTP/1.1 502 Bad Gateway
Content-Disposition: attachment
Content-Type: application/json
X-Fc-Request-Id: 1-64f6df91-fe144d52e4fd27afe3d8dd6f
Content-Length: 21
Internal Server Error
X-Fc-Request-Id の値を使用して、関数の呼び出しログで完全なエラー詳細を検索してください。
関連トピック
ビルトインランタイム用の関数コードを作成している場合は、ご利用の言語のハンドラに関するドキュメントをご参照ください。