Function Compute は、API Gateway をイベントソースとして使用することをサポートしています。API のバックエンドサービスとして Function Compute を構成できます。Function Compute をバックエンドサービスとして使用するように構成された API Gateway インスタンスがリクエストを受信すると、API Gateway は関連付けられた関数をトリガーして実行します。関数が実行を完了すると、Function Compute は結果を API Gateway に返送します。
背景
API Gateway トリガーは HTTP トリガーと同様に機能し、Web アプリケーションの構築に使用できます。HTTP トリガーとは異なり、API Gateway トリガーでは、IP ホワイトリストやブラックリストの設定など、高度な操作を実行できます。
API Gateway は、イベント関数と Web 関数の両方をバックエンドサービスとして使用できるように構成できます。Function Compute が API Gateway と統合されると、これらの関数は API を介してクライアントに安全に公開できます。この設定により、認証、トラフィック制御、データ変換など、さまざまな懸念事項を効果的に管理できます。
イベント関数を作成し、API Gateway と統合する
ステップ 1: イベント関数を作成する
Function Compute コンソールでイベント関数を作成します。詳細については、「イベント関数を作成する」をご参照ください。
ステップ 2: Function Compute をバックエンドサービスとして使用する API を作成する
API Gateway でバックエンドサービスを作成し、バックエンドサービスの URL が Function Compute サービスを指すように構成する必要があります。
API Gateway コンソール にログインします。左側のナビゲーションウィンドウで、[API の管理] > [バックエンドサービス] を選択します。上部のナビゲーションバーで、リージョンを選択します。次に、右上隅にある [バックエンドサービスの作成] をクリックし、次の図に示すようにパラメーターを構成して、[確認] をクリックします。

[バックエンドサービス] ページで、作成したバックエンドサービスをクリックします。[バックエンドサービスの定義] ページで、[本番環境] タブをクリックします。[基本情報] セクションで、[作成] をクリックします。ステップ 1 で作成したイベント関数を選択し、[公開] をクリックします。

API グループを作成します。
説明関数と同じリージョンに API グループを作成することをお勧めします。API が別のリージョンにある場合、インターネット経由で Function Compute サービスにアクセスする必要があり、トラフィックコストが発生します。データセキュリティとネットワーク遅延の要件が厳しい場合は、関数と同じリージョンに API グループが作成されていることを確認してください。
API を作成して公開します。
以下に概説されている必須パラメーターを構成します。残りはデフォルト設定のままにしておくことができます。

パラメーター
構成手順
セキュリティ認証
認証なしを選択します。
構成モード
既存のバックエンドサービスを使用するを選択します。
バックエンドサービスタイプ
Function Compute を選択します。
バージョン
Function Compute V3.0 を選択します。
関数タイプ
イベント関数を選択します。
バックエンドサービス
イベント関数を指す、作成したバックエンドサービスを選択します。
ステップ 3: 関数コードを記述する
Function Compute コンソール にログインします。左側のナビゲーションウィンドウで、[関数] をクリックします。
上部のナビゲーションバーで、リージョンを選択します。[関数] ページで、管理する関数をクリックします。
[関数の詳細] ページの [コード] タブで、コードエディタにコードを記述し、[デプロイ] をクリックします。
さまざまな言語のサンプルコードは次のとおりです。
Node.js
module.exports.handler = function(event, context, callback) { var event = JSON.parse(event); var content = { path: event.path, method: event.method, headers: event.headers, queryParameters: event.queryParameters, pathParameters: event.pathParameters, body: event.body // ここに独自のロジックを記述できます。 } var response = { isBase64Encoded: false, statusCode: '200', headers: { 'x-custom-header': 'header value' }, body: content }; callback(null, response) };Python
# -*- coding: utf-8 -*- import json def handler(event, context): event = json.loads(event) content = { 'path': event['path'], 'method': event['httpMethod'], 'headers': event['headers'], 'queryParameters': event['queryParameters'], 'pathParameters': event['pathParameters'], 'body': event['body'] } # ここに独自のロジックを記述できます。 rep = { "isBase64Encoded": "false", "statusCode": "200", "headers": { "x-custom-header": "no" }, "body": content } return json.dumps(rep)PHP
<?php function handler($event, $context) { $event = json_decode($event, $assoc = true); $content = [ 'path' => $event['path'], 'method' => $event['httpMethod'], 'headers' => $event['headers'], 'queryParameters' => $event['queryParameters'], 'pathParameters' => $event['pathParameters'], 'body' => $event['body'], ]; $rep = [ "isBase64Encoded" => "false", "statusCode" => "200", "headers" => [ "x-custom-header" => "no", ], "body" => $content, ]; return json_encode($rep); }Java
Function Compute 用に Java でプログラミングする場合、事前定義されたハンドラーメソッドを使用するクラスを実装する必要があります。2 つの事前定義されたハンドラーメソッドがあります。Java ランタイムの詳細については、「コードパッケージのコンパイルとデプロイ」をご参照ください。
(推奨) PojoRequestHandler<I, O> ハンドラーを使用します。
import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.PojoRequestHandler; import java.util.HashMap; import java.util.Map; public class ApiTriggerDemo implements PojoRequestHandler<ApiRequest, ApiResponse> { public ApiResponse handleRequest(ApiRequest request, Context context) { // API リクエスト情報を取得します。 context.getLogger().info(request.toString()); String path = request.getPath(); String httpMethod = request.getHttpMethod(); String body = request.getBody(); context.getLogger().info("path:" + path); context.getLogger().info("httpMethod:" + httpMethod); context.getLogger().info("body:" + body); // ここに独自のロジックを記述できます。 // API レスポンスの例。 Map headers = new HashMap(); boolean isBase64Encoded = false; int statusCode = 200; String returnBody = ""; return new ApiResponse(headers,isBase64Encoded,statusCode,returnBody); } }次のサンプルでは、2 つの
POJOクラス、ApiRequestとApiResponseを定義しています。説明POJOクラスのset()メソッドとget()メソッドを指定する必要があります。import java.util.Map; public class ApiRequest { private String path; private String httpMethod; private Map headers; private Map queryParameters; private Map pathParameters; private String body; private boolean isBase64Encoded; @Override public String toString() { return "Request{" + "path='" + path + '\'' + ", httpMethod='" + httpMethod + '\'' + ", headers=" + headers + ", queryParameters=" + queryParameters + ", pathParameters=" + pathParameters + ", body='" + body + '\'' + ", isBase64Encoded=" + isBase64Encoded + '}'; } public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getHttpMethod() { return httpMethod; } public void setHttpMethod(String httpMethod) { this.httpMethod = httpMethod; } public Map getHeaders() { return headers; } public void setHeaders(Map headers) { this.headers = headers; } public Map getQueryParameters() { return queryParameters; } public void setQueryParameters(Map queryParameters) { this.queryParameters = queryParameters; } public Map getPathParameters() { return pathParameters; } public void setPathParameters(Map pathParameters) { this.pathParameters = pathParameters; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } public boolean getIsBase64Encoded() { return this.isBase64Encoded; } public void setIsBase64Encoded(boolean base64Encoded) { this.isBase64Encoded = base64Encoded; } }import java.util.Map; public class ApiResponse { private Map headers; private boolean isBase64Encoded; private int statusCode; private String body; public ApiResponse(Map headers, boolean isBase64Encoded, int statusCode, String body) { this.headers = headers; this.isBase64Encoded = isBase64Encoded; this.statusCode = statusCode; this.body = body; } public Map getHeaders() { return headers; } public void setHeaders(Map headers) { this.headers = headers; } public boolean getIsBase64Encoded() { return isBase64Encoded; } public void setIsBase64Encoded(boolean base64Encoded) { this.isBase64Encoded = base64Encoded; } public int getStatusCode() { return statusCode; } public void setStatusCode(int statusCode) { this.statusCode = statusCode; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } }次のコードは、pom.xml ファイルの例を示しています。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>apiTrigger</groupId> <artifactId>apiTrigger</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-core</artifactId> <version>1.0.0</version> </dependency> </dependencies> </project>
StreamRequestHandler ハンドラーを使用します。
このハンドラーを使用するには、
InputStreamをPOJOクラスに変換する必要があります。次のサンプルコードは、このハンドラーの使用方法を示しています。pom.xml ファイルの構成は、PojoRequestHandler<I, O> ハンドラーを使用する場合と同じです。
import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.fc.runtime.Context; import com.google.gson.Gson; import java.io.*; import java.util.Base64; import java.util.HashMap; import java.util.Map; public class ApiTriggerDemo2 implements StreamRequestHandler { public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) { try { // InputStream を文字列に変換します。 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); StringBuffer stringBuffer = new StringBuffer(); String string = ""; while ((string = bufferedReader.readLine()) != null) { stringBuffer.append(string); } String input = stringBuffer.toString(); context.getLogger().info("inputStream: " + input); Request req = new Gson().fromJson(input, Request.class); context.getLogger().info("input req: "); context.getLogger().info(req.toString()); String bodyReq = req.getBody(); Base64.Decoder decoder = Base64.getDecoder(); context.getLogger().info("body: " + new String(decoder.decode(bodyReq))); // ここに独自のロジックを記述できます。 // 返された結果。 Map headers = new HashMap(); headers.put("x-custom-header", " "); boolean isBase64Encoded = false; int statusCode = 200; Map body = new HashMap(); Response resp = new Response(headers, isBase64Encoded, statusCode, body); String respJson = new Gson().toJson(resp); context.getLogger().info("outputStream: " + respJson); outputStream.write(respJson.getBytes()); } catch (IOException e) { e.printStackTrace(); } finally { try { outputStream.close(); inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } class Request { private String path; private String httpMethod; private Map headers; private Map queryParameters; private Map pathParameters; private String body; private boolean isBase64Encoded; @Override public String toString() { return "Request{" + "path='" + path + '\'' + ", httpMethod='" + httpMethod + '\'' + ", headers=" + headers + ", queryParameters=" + queryParameters + ", pathParameters=" + pathParameters + ", body='" + body + '\'' + ", isBase64Encoded=" + isBase64Encoded + '}'; } public String getBody() { return body; } } // Function Compute は、次の JSON 形式で API Gateway にレスポンスを返します。 class Response { private Map headers; private boolean isBase64Encoded; private int statusCode; private Map body; public Response(Map headers, boolean isBase64Encoded, int statusCode, Map body) { this.headers = headers; this.isBase64Encoded = isBase64Encoded; this.statusCode = statusCode; this.body = body; } } }
ステップ 4: 関数の入力パラメーターを構成する
API Gateway が関数をトリガーすると、イベントオブジェクトの形式で情報を関数に渡します。この情報を使用して、関数をデバッグできます。
関数詳細ページの [コード] タブで、
アイコンをクリックし、[関数をテスト] の隣にあるドロップダウン リストから [テスト パラメーターの構成] を選択します。[テストパラメーターの構成] パネルで、[新しいテストイベントの作成] タブまたは [既存のテストイベントの変更] タブをクリックし、イベント名とイベントコンテンツを入力して、[OK] をクリックします。
イベントオブジェクトの例は次のとおりです。
{ "path":"api request path", "httpMethod":"request method name", "headers":{all headers,including system headers}, "queryParameters":{query parameters}, "pathParameters":{path parameters}, "body":"string of request payload", "isBase64Encoded":"true|false, indicate if the body is Base64-encode" }次の表に、イベントオブジェクトのパラメーターを示します。
パラメーター
タイプ
説明
path
文字列
API リクエストパス。
httpMethod
文字列
リクエストメソッド。有効な値: GET、POST、PUT、DELETE。
headers
オブジェクト
リクエストヘッダー情報。システムヘッダーとカスタムヘッダーの両方を含む、すべてのリクエストヘッダーが含まれます。
queryParameters
オブジェクト
クエリパラメーター。通常は、URL の疑問符の後に表示されるキーと値のペアの形式です。
pathParameters
オブジェクト
パスパラメーター。通常は URL の一部であり、特定のリソースを識別するために使用されます。
body
文字列
リクエスト本文。
isBase64Encoded
ブール値
リクエスト本文が Base64 エンコーディングであるかどうかを指定します。
説明isBase64Encodedの値がtrueの場合、API Gateway が Function Compute に送信する body コンテンツは Base64 エンコードされます。Function Compute は、コンテンツを処理する前に、body コンテンツを Base64 形式からデコードします。isBase64Encodedの値がfalseの場合、API Gateway は body コンテンツで Base64 エンコーディングを実行しなかったため、Function Compute は body コンテンツを直接取得できます。
[関数のテスト] をクリックします。
ステップ 5: 結果を表示する
関数が実行された後、[コード] タブで結果を表示できます。
Function Compute は、次の JSON 形式で解析するために、実行結果を API Gateway に送信します。次のコードスニペットは、返された結果の例を示しています。
{
"isBase64Encoded":true|false,
"statusCode":httpStatusCode,
"headers":{response headers},
"body":"..."
} イベント関数が API Gateway と統合されている場合の形式要件
API Gateway が、Function Compute をバックエンドサービスとして使用する API 操作のリクエストを受信すると、API Gateway はリクエストパラメーターをマップ形式のキーと値のペアに変換し、リクエストを Function Compute に送信します。Function Compute はリクエストを処理し、次の図に示すように、状態コード、ヘッダー、本文などの情報を含むレスポンスを API Gateway に返します。API Gateway は、Function Compute から返されたレスポンス内の情報を API レスポンスの状態コード、ヘッダー、本文にマッピングし、API レスポンスをクライアントに返します。

Web 関数を作成し、API Gateway と統合する
ステップ 1: Web 関数を作成する
Function Compute コンソールで Web 関数を作成します。詳細については、「ステップ 1: Web 関数を作成する」をご参照ください。
作成した Web 関数に対して HTTP トリガーが自動的に作成されます。後で使用するために内部エンドポイントをコピーします。

ステップ 2: バックエンドサービスを作成する
API Gateway でバックエンドサービスを作成し、バックエンドサービスの URL が Function Compute サービスを指すように構成する必要があります。
API Gateway コンソール にログインします。左側のナビゲーションウィンドウで、[API の管理] > [バックエンドサービス] を選択します。上部のナビゲーションバーで、リージョンを選択します。次に、右上隅にある [バックエンドサービスの作成] をクリックし、次の図に示すようにパラメーターを構成して、[確認] をクリックします。

[バックエンドサービス] ページで、作成したバックエンドサービスをクリックします。[バックエンドサービスの定義] ページで、[本番環境] タブをクリックします。[基本情報] セクションで、[作成] をクリックします。ステップ 1 でコピーした内部エンドポイントを貼り付けて、[公開] をクリックします。

手順 3: API を作成して公開する
このステップでは、外部アプリケーションが特定の方法で内部 Web 関数を呼び出すことができる API を作成します。API グループは、複数の関連 API を整理および管理するために使用され、統一されたセキュリティポリシーとトラフィック制御対策の実装を容易にします。
API Gateway コンソール にログインします。左側のナビゲーションウィンドウで、[API の管理] > [API グループ] を選択します。[API グループ] ページで、[グループの作成] をクリックします。
[グループの作成] ダイアログボックスで、[インスタンス] ドロップダウンリストからインスタンスを選択し、[グループ名] パラメーターを
FC-Groupに、[basepath] パラメーターを/に設定して、[確認] をクリックします。
説明関数と同じリージョンに API グループを作成することをお勧めします。API が別のリージョンにある場合、インターネット経由で Function Compute サービスにアクセスする必要があり、トラフィックコストが発生します。データセキュリティとネットワーク遅延の要件が厳しい場合は、関数と同じリージョンに API グループが作成されていることを確認してください。
[API グループ] ページで、作成した API グループを見つけ、[アクション] 列の [API の管理] をクリックし、[API の作成] をクリックします。次のパラメーターを構成し、[次へ] をクリックします。

[API リクエストの定義] ステップで、[リクエストパス] パラメーターを
/に設定し、その他のパラメーターにはデフォルト値を使用し、[次へ] をクリックします。[バックエンドサービスの定義] ステップで、次のパラメーターを構成し、[次へ] をクリックします。

[レスポンスの定義] ステップで、デフォルト設定を維持し、[作成] をクリックします。表示される[メモ] ダイアログボックスで、[公開] をクリックします。
[API の公開] ダイアログボックスで、次のパラメーターを構成し、[公開] をクリックします。

ステップ 4: アプリケーションを作成し、API を呼び出す権限を付与する手順 4: アプリケーションを作成し、API を呼び出すように承認する
アプリケーションは、API サービスにリクエストを行うときに認証に使用される ID を表します。この例では、Alibaba Cloud アプリステップ 3: API を作成して公開する の[セキュリティ認証] パラメーターに[Alibaba Cloud アプリ] が選択されています。したがって、API が公開された後、アプリケーションを作成し、API を呼び出す権限を付与する必要があります。
API Gateway コンソール にログインします。左側のナビゲーションウィンドウで、[API の呼び出し] > [アプリ] を選択します。
[アプリ] ページで、右上隅にある [アプリの作成] をクリックします。[アプリの作成] ダイアログボックスで、[アプリ名] を
fcAppに設定し、[確認] をクリックします。[アプリ] ページで、作成した
fcAppアプリケーションをクリックします。[アプリの詳細] ページで、AppKeyとAppCodeの 2 つの認証方式が利用可能であることがわかります。AppKey方式には、ユーザー名とパスワードのペアと同様に機能するAppKeyとAppSecretのペアが含まれています。API を呼び出すときは、AppKeyをパラメーターとして渡す必要があります。AppSecretは署名の計算に使用されます。API Gateway は AppKey-AppSecret ペアを検証して、ID を認証します。
左側のナビゲーションウィンドウで、[API の管理] > [API] を選択します。[API] ページで、作成した API を見つけ、
> [承認] を [アクション] 列でクリックします。[承認] ダイアログボックスで、[ステージ] パラメーターを [本番環境] に設定します。[承認するアプリの選択] セクションの検索バーに
fcAppと入力します。検索結果で fcApp アプリケーションを選択し、[アクション] 列の [追加] をクリックし、[確認] をクリックします。アプリケーションが API の呼び出しを承認されたことを知らせるメッセージが表示されます。
手順 5: 結果を確認する
次のセクションでは、AppCode ベースの認証方式を使用して、業務システムで公開済みの API を呼び出す方法について説明します。この例では、Curl コマンドを使用して API 呼び出しを行います。
API Gateway コンソール にログインします。左側のナビゲーションウィンドウで、[API の呼び出し] > [アプリ] を選択します。[アプリ] ページで、承認されたアプリケーションをクリックし、表示されるページで AppCode を取得します。次に、次のサンプルコードを使用して API を呼び出します。
curl -i -X GET "http://fd6f8e2b7bf44ab181a56****-cn-hangzhou.alicloudapi.com" -H "Authorization:APPCODE 7d2b7e4945ce44028ab00***"よくある質問
API Gateway によって関数の実行がトリガーされるとエラーコード 502 が返されますが、関数ログには関数が正常に実行されたと表示されます。この問題を解決するにはどうすればよいですか?
API Gateway では、Function Compute が特定の形式でレスポンスを返す必要があります。レスポンスが予期される形式でない場合、API Gateway はバックエンドサービスが利用できないと見なします。API Gateway と Function Compute の統合の形式要件の詳細については、「さまざまなトリガーのイベント形式」と「ステップ 5: 結果を表示する」をご参照ください。
返されたレスポンスのコンテンツタイプを設定するにはどうすればよいですか?
次の図に示すように、API を作成するときに、[レスポンスの定義] ステップでレスポンスのコンテンツタイプを指定できます。詳細については、「API Gateway を使用して Function Compute 3.0 の Web 関数をトリガーする」をご参照ください。
以前に呼び出されたが、しばらく呼び出されていない関数を API Gateway を使用して呼び出すと、エラーコード 503 が返されます。この問題を解決するにはどうすればよいですか?
関数がしばらく呼び出されていない場合、次回の呼び出し時に新しい実行環境を準備する必要があるため、コールドスタートの遅延が発生します。これにより、呼び出しが完了する前に API Gateway でタイムアウトが発生し、API Gateway がバックエンドサービスを利用できないと見なす可能性があります。この問題を解決するには、API Gateway のタイムアウト期間を延長します。
API Gateway から Function Compute に渡されるリクエストの body パラメーターが Base64 エンコードされるのはなぜですか?
リクエストの本文は、コンテンツの送信エラーや損失を防ぐために Base64 エンコードされます。ただし、API Gateway によってフォーム形式で送信される本文は Base64 エンコードされません。フォーム形式を使用する場合は、API Gateway で[入力パラメーターのマッピング] を選択する必要があります。isBase64 の値が true か false かを確認することをお勧めします。isBase64 の値が true の場合、Function Compute はコンテンツを処理する前に、body コンテンツを Base64 形式からデコードします。API Gateway によって Function Compute に渡されるイベント形式の詳細については、「さまざまなトリガーのイベント形式」をご参照ください。