このトピックでは、カスタムランタイムにおける関数の呼び出しメソッド、制限事項、およびコード例について説明します。
背景情報
カスタムランタイムは、HTTP サーバーをホストできます。Function Compute (FC) は、関数の呼び出しリクエストを HTTP リクエストに変換し、ご利用の HTTP サーバーに送信します。その後、FC はサーバーからのレスポンスを関数の呼び出しレスポンスに変換し、クライアントに返します。次の図にこのプロセスを示します。
関数は、次の 2 つの方法のいずれかで呼び出すことができます:
-
HTTP 呼び出し (推奨): HTTP トリガーまたはカスタムドメイン名を使用して、HTTP 経由で関数を呼び出します。
-
API 呼び出し: SDK やイベントソースなどを使用して、InvokeFunction API を呼び出すことで関数を呼び出します。
HTTP リクエストとレスポンスのフォーマットは、呼び出しメソッドによって異なります。
制限事項
-
各関数バージョンまたはエイリアスに対して作成できる HTTP トリガーは 1 つだけです。詳細については、「バージョンの管理」および「エイリアスの管理」をご参照ください。
-
HTTP リクエストの制限
-
リクエストヘッダーには、x-fc- で始まるカスタムフィールドや、次のフィールドを含めることはできません:
-
connection
-
keep-alive
-
-
リクエストが次の制限を超えた場合、FC は状態コード
400とエラーコードInvalidArgumentを返します。-
ヘッダーサイズ: ヘッダー内のすべてのキーと値の合計サイズは 8 KB を超えることはできません。
-
パスサイズ: すべてのクエリパラメーターを含むパスの合計サイズは 4 KB を超えることはできません。
-
本文サイズ: 同期呼び出しのリクエスト本文の合計サイズは 32 MB を超えることはできません。非同期呼び出しのリクエスト本文の合計サイズは 128 KB を超えることはできません。
-
-
-
HTTP レスポンスの制限
-
レスポンスヘッダーには、x-fc- で始まるカスタムフィールドや、次のフィールドを含めることはできません:
-
connection
-
content-length
-
date
-
keep-alive
-
server
-
content-disposition:attachment
説明セキュリティ上の理由から、Function Compute のデフォルトの aliyuncs.com ドメインを使用する場合、サーバーはレスポンスに content-disposition: attachment ヘッダーを強制的に追加します。このヘッダーにより、レスポンスはブラウザで添付ファイルとしてダウンロードされます。この制限を解除するには、カスタムドメイン名を設定してください。
-
-
レスポンスが次の制限を超えた場合、FC は状態コード
502とエラーコードBadResponseを返します。-
ヘッダーサイズ: ヘッダー内のすべてのキーと値の合計サイズは 8 KB を超えることはできません。
-
-
-
補足事項
カスタムドメイン名をバインドすることで、さまざまな HTTP アクセスパスを関数にマップできます。詳細については、「カスタムドメイン名を設定」をご参照ください。
HTTP 呼び出し (推奨)
HTTP 呼び出しの場合、FC はパススルーモードを使用します。クライアントの HTTP リクエストをご利用の HTTP サーバーに転送し、サーバーのレスポンスをクライアントに返します。FC は一部のシステム予約フィールドをパススルーしません。詳細については、「制限事項」をご参照ください。
リクエストヘッダー
HTTP トリガーまたはカスタムドメイン名で関数を呼び出す場合、以下のリクエストヘッダーを使用してリクエストを制御します。
|
名前 |
タイプ |
必須 |
例 |
説明 |
|
X-Fc-Invocation-Type |
String |
いいえ |
Sync |
呼び出しメソッドを指定します。詳細については、「呼び出しメソッド」をご参照ください。有効な値は次のとおりです:
|
|
X-Fc-Log-Type |
String |
いいえ |
Tail |
レスポンスにログを返すかどうかを指定します。有効な値は次のとおりです:
|
レスポンスヘッダー
FC は、以下のデフォルトヘッダーをレスポンスに追加します。
|
名前 |
説明 |
例 |
|
X-Fc-Request-Id |
関数呼び出しの一意のリクエスト ID。 |
dab25e58-9356-4e3f-97d6-f044c4**** |
API 呼び出し
InvokeFunction API を使用して関数が呼び出されると、FC は API リクエストを HTTP リクエストに変換し、ご利用の HTTP サーバーに送信します。この変換は次のルールに従います:
-
InvokeFunction リクエストの
eventパラメーターは、HTTP リクエストのメッセージ本文になります。 -
パスは/invokeです。 -
メソッドはPOSTです。 -
Content-Typeリクエストヘッダーはapplication/octet-streamです。
FC は、ご利用の HTTP サーバーからのレスポンスを InvokeFunction API レスポンスに変換し、クライアントに返します。この変換は次のルールに従います:
-
HTTP レスポンスの本文は、InvokeFunction のレスポンス本文になります。
-
この変換では、HTTP レスポンスのヘッダーと状態コードは破棄されます。
InvokeFunction API リクエスト変換の例
|
呼び出しリクエスト |
HTTP リクエスト |
|
Invoke API リクエストの内容:
|
|
InvokeFunction API レスポンスの例
|
HTTP レスポンス |
呼び出しレスポンス |
|
|
|
|
Function Compute のレスポンスコードとレスポンスヘッダー
カスタムランタイムは、本質的にはユーザーが実装する HTTP サーバーです。したがって、各関数呼び出しは HTTP リクエストであり、各レスポンスには状態コードとレスポンスヘッダーが含まれます。
-
レスポンスの
status code-
200: 成功。 -
404: 失敗。
-
-
レスポンスヘッダー
x-fc-status-
200: 成功。 -
404: 失敗。
-
x-fc-status レスポンスヘッダーを使用して、関数の実行ステータスを FC にレポートできます。
-
x-fc-statusヘッダーを設定しない場合、FC はデフォルトで呼び出しが成功したと見なします。ただし、関数でエラーが発生してもそれをレポートしない場合、FC はその失敗を認識しません。これはビジネスロジックに影響しないかもしれませんが、モニタリングと可観測性に影響します。次のコードに例を示します:print("FC Invoke Start RequestId: " + rid) data = request.stream.read() print("Path: " + path) print("Data: " + str(data)) # Simulate an exception to trigger a runtime error raise Exception("mock exception") print("FC Invoke End RequestId: " + rid) return "Hello, World!" if __name__ == '__main__': app.run(host='0.0.0.0', port=9000) -
x-fc-statusヘッダーを設定すると、関数でエラーが発生したときに FC に失敗をレポートし、エラースタックトレースをログに出力できます。たとえば、x-fc-statusレスポンスヘッダーを404に設定すると、FC はその呼び出しをInvocationError型の失敗として識別し、呼び出し結果はmock exceptionとなります。次の app.py ファイルに例を示します:@app.route('/', defaults={'path': ''}) @app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE']) def hello_world(path): rid = request.headers.get(REQUEST_ID_HEADER) print("FC Invoke Start RequestId: " + rid) try: raise Exception("mock exception") except Exception as e: print("FC Invoke End RequestId: " + rid + ", Error: Unhandled Exception") print(str(e)) return str(e), 404, [{"x-fc-status", "404"}]
返される HTTP レスポンスでは、status code と x-fc-status ヘッダーの両方を設定することを推奨します。
コード例
関数のトリガーを設定する際、任意のプログラミング言語で HTTP サーバーを実装できます。このトピックでは、Python を例として使用します。
このサンプルコードには、 Python 環境と Flask ライブラリが必要です。関数を作成する際に、Web 関数 を選択し、ランタイムとして Python 3.10 を使用することをお勧めします。
import os
from flask import Flask
from flask import request
REQUEST_ID_HEADER = 'x-fc-request-id'
app = Flask(__name__)
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def hello_world(path):
rid = request.headers.get(REQUEST_ID_HEADER)
data = request.stream.read()
print("Path: " + path)
print("Data: " + str(data))
return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000)
このコードは次のように動作します:
-
@app.route('/', defaults={'path': ''}): これは、ルートパスに対応するデフォルトのルートです。 -
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE']): これは、GET、POST、PUT、DELETE リクエストを処理できるパスパラメーターを持つ動的ルートです。このルートは、パスパラメーターの値を hello_world 関数の path 引数として渡します。 -
rid = request.headers.get(REQUEST_ID_HEADER): リクエストヘッダーからx-fc-request-idフィールドの値を取得します。 -
data = request.stream.read(): リクエストの内容を読み取り、data変数に割り当てます。 -
return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]: "Hello, World!" を含むレスポンス本文、状態コード 200、およびFunction-Nameレスポンスヘッダーを返します。