Function Compute は、API Gateway をイベントソースとしてサポートしています。API のバックエンドサービスとして Function Compute を設定できます。バックエンドサービスが Function Compute に設定された API Gateway にリクエストが到達すると、関連付けられた関数が起動されます。Function Compute は、実行結果を API Gateway に返します。
背景情報
API Gateway トリガーは HTTP トリガーと類似しており、Web アプリケーションの構築に使用できます。HTTP トリガーと比較して、API Gateway では IP アドレスホワイトリストやブラックリストの設定など、高度な操作が可能です。
API Gateway は、イベント関数および Web 関数の両方をバックエンドサービスとしてサポートしています。API Gateway を Function Compute に接続すると、認証、トラフィックシェーピング、データ変換などのタスクを処理しながら、関数を安全に API 経由で公開できます。
イベント関数の作成と API Gateway への接続
ステップ 1:イベントトリガー付き関数の作成
Function Compute 3.0 コンソールでイベント関数を作成します。詳細については、「イベント関数の作成」をご参照ください。
ステップ 2:バックエンドサービスが Function Compute の API の作成
API Gateway でバックエンドサービスを定義し、そのエンドポイントを Function Compute に接続するよう構成します。
API Gateway コンソールにログインし、リージョンを選択します。左側のナビゲーションウィンドウで、API 管理 > バックエンドサービス を選択します。右上隅の バックエンドサービスの作成 をクリックします。以下の情報を構成し、確認 をクリックします。

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

API グループを作成します。
説明関数と同じリージョンに API グループを作成してください。異なるリージョンの場合、API はパブリックネットワーク経由でご利用の Function Compute サービスにアクセスする必要があり、トラフィック料金が発生します。データセキュリティおよびネットワーク遅延に対して高い要件がある場合は、API と関数を同じリージョンに配置してください。
API の作成および公開を行います。
以下の主要な設定項目を構成します。その他の項目はデフォルト設定のままとします。

設定項目
例
セキュリティ 認証
認証なし
設定モード
既存のバックエンドサービスを使用
バックエンドサービスのタイプ
Function Compute
プロダクトバージョン
Function Compute 3.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
Java を使用する場合、Function Compute の事前定義ハンドラを実装するクラスを作成する必要があります。以下の 2 つの事前定義ハンドラのいずれかを実装できます。Function Compute の 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の定義を以下に示します。説明set()およびget()メソッドは、POJOクラスで完全に実装されている必要があります。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 は、API Gateway に応答を返す際に、以下の JSON 形式で返す必要があります。 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 が関数をトリガーすると、API 関連の情報がイベントとして関数の入力パラメーターに渡されます。このイベント情報を使用して、関数コードが正しく動作するかどうかをテストできます。
関数の詳細ページの [コード] タブで、[テスト関数] の横にある
アイコンをクリックし、ドロップダウンリストから [テストパラメーターの設定] を選択します。テストパラメーターの設定 パネルで、新規テストイベントの作成 または 既存のテストイベントの変更 を選択します。イベント名および内容を入力し、[OK] をクリックします。
以下の例に、イベントの形式を示します:
{ "path":"API リクエストパス", "httpMethod":"リクエストメソッド名", "headers":{すべてのヘッダー(システムヘッダーを含む)}, "queryParameters":{クエリパラメーター}, "pathParameters":{パスパラメーター}, "body":"リクエストペイロードの文字列", "isBase64Encoded":"true|false、ボディが Base64 エンコードされているかどうかを示す" }以下の表に、イベントパラメーターのフィールドを説明します。
パラメーター
型
説明
path
String
API リクエストのパスです。
httpMethod
String
GET、POST、PUT、DELETE などのリクエストメソッド名です。
headers
Object
システムヘッダーおよびカスタムヘッダーを含むすべてのリクエストヘッダー情報を含みます。
queryParameters
Object
クエリパラメーターで、通常は URL の疑問符 (?) の後にキーと値のペアとして表示されます。
pathParameters
Object
パスパラメーターで、通常は URL の一部であり、特定のリソースを識別するために使用されます。
body
String
リクエストボディです。
isBase64Encoded
Boolean
リクエストボディが Base64 エンコードされているかどうかを示します。
説明isBase64Encodedの値がtrueの場合、API Gateway から Function Compute に渡される body コンテンツは Base64 エンコードされています。Function Compute は、処理前に body コンテンツを Base64 デコードする必要があります。isBase64Encodedの値がfalseの場合、API Gateway は body コンテンツを Base64 エンコードしません。関数内で body コンテンツを直接取得できます。
関数のテスト をクリックします。
ステップ 5:結果の検証
実行が完了すると、コード タブの上部に結果を表示できます。
Function Compute は、API Gateway に実行結果を以下の JSON 形式で返す必要があります。API Gateway は、この結果を解析します。以下の例に、応答形式を示します:
{
"isBase64Encoded":true|false,
"statusCode":httpStatusCode,
"headers":{response headers},
"body":"..."
} イベント関数を API Gateway に接続する際の形式要件
API Gateway が Function Compute を呼び出す場合、API 関連のデータをマップに変換して Function Compute サービスに渡します。処理後、Function Compute は指定された出力形式で statusCode、headers、body などのデータを返します。API Gateway は、Function Compute から返されたコンテンツを statusCode、headers、body フィールドにマップし、クライアントに返します。

Web 関数の作成と API Gateway への接続
ステップ 1:Web 関数の作成
Function Compute 3.0 コンソールで Web 関数を作成します。詳細については、「Web 関数の作成」をご参照ください。
デフォルトで、Web 関数には HTTP トリガーが作成されます。後で使用するため、内部ネットワークのエンドポイントをコピーします。

ステップ 2:バックエンドサービスの作成
API Gateway でバックエンドサービスを定義し、そのエンドポイントを Function Compute に接続するよう構成します。
API Gateway コンソールにログインし、リージョンを選択します。左側のナビゲーションウィンドウで、API 管理 > バックエンドサービス を選択します。右上隅の バックエンドサービスの作成 をクリックします。以下の情報を構成し、確認 をクリックします。

バックエンドサービスページで、先ほど作成したバックエンドサービスをクリックして、バックエンドサービス定義ページに移動します。本番環境 タブをクリックします。基本情報 セクションで、作成 をクリックします。ステップ 1 で作成した Web 関数のトリガーの内部ネットワークエンドポイントを入力し、公開 をクリックします。

ステップ 3:API の作成および公開
外部アプリケーションが指定された方法で内部の Web 関数サービスを呼び出せるように、API を作成します。API グループを使用して複数の関連 API オペレーションを整理および管理することで、統一されたセキュリティポリシーおよびトラフィックシェーピング対策の実装を簡素化できます。
API Gateway コンソールにログインします。左側のナビゲーションウィンドウで、API 管理 > API グループ を選択し、グループの作成 をクリックして API を管理します。
グループの作成 ダイアログボックスで、インスタンス: を選択し、グループ名 に
FC-Groupを入力し、BasePath を/に設定します。その後、確認 をクリックします。
説明関数と同じリージョンに API グループを作成してください。異なるリージョンの場合、API はパブリックネットワーク経由でご利用の Function Compute サービスにアクセスする必要があり、トラフィック料金が発生します。データセキュリティおよびネットワーク遅延に対して高い要件がある場合は、API と関数を同じリージョンに配置してください。
グループ一覧ページで対象のグループを見つけ、操作 列で API の管理 をクリックします。その後、API の作成 をクリックし、以下の情報を構成して、次へ をクリックします。

API リクエストの定義 構成タブで、リクエストパス を
/に設定し、その他の項目はデフォルト設定のままにして、次へ をクリックします。バックエンドサービスの定義 構成タブで、図に示す設定を構成し、次へ をクリックします。

レスポレスポンス 構成タブで、デフォルト設定のままにして、作成 をクリックします。API が作成されたら、表示されるダイアログボックスで 公開 をクリックします。
API の公開 ダイアログボックスで、以下の設定項目を構成し、公開 をクリックします。

ステップ 4:アプリケーションの作成および API 権限付与
アプリケーション(APP)は、API サービスを呼び出す際の ID として機能します。ステップ 3:API の作成および公開 では、認証方式を Alibaba Cloud APP に設定しました。そのため、API を公開した後、APP を作成し、API へのアクセス権限を APP に付与する必要があります。
API Gateway コンソールにログインします。左側のナビゲーションウィンドウで、API 呼び出し > アプリケーション管理 を選択します。
アプリケーションと権限付与 ページの右上隅で、アプリの作成 をクリックします。アプリの作成 ページで、アプリ名: に
fcAppを入力し、確認 をクリックします。作成した
fcAppアプリケーションの名前をクリックして、アプリの詳細 ページに移動します。Alibaba Cloud APP の認証方式には、AppKeyおよびAppCodeの 2 つがあります。AppKey方式では、AppKeyとAppSecretを使用します。これは、アカウントとパスワードと考えることができます。API を呼び出す際、AppKeyがパラメーターとして渡され、AppSecretが署名計算に使用されます。ゲートウェイはこのキーペアを使用して、お客様の ID を認証します。
左側のナビゲーションウィンドウで、API 管理 > API を選択します。API 一覧ページで、作成した API を見つけます。操作 列で、
> 承認 を選択します。権限付与ページで、ステージ: を 本番環境 に設定します。
fcAppアプリケーションを検索し、追加 をクリックし、確認 をクリックします。権限付与が成功したことを示すメッセージが表示されます。
ステップ 5:結果の検証
このセクションでは、業務システムで AppCode 認証を使用して公開済みの API を呼び出す方法について説明します。例として curl コマンドを使用します。
API Gateway コンソールにログインします。左側のナビゲーションウィンドウで、API 呼び出し > アプリケーション管理 を選択します。アプリケーションと権限付与 ページで、権限付与済みの APP を見つけ、それをクリックして APPCode を取得します。その後、以下の例に示すように API を呼び出します。
curl -i -X GET "http://fd6f8e2b7bf44ab181a56****-cn-hangzhou.alicloudapi.com" -H "Authorization:APPCODE 7d2b7e4945ce44028ab00***"よくある質問
API Gateway トリガーが関数を実行した際に 502 エラーが報告されますが、関数のログには正常に実行されたことが示されています。なぜこのような現象が発生するのでしょうか?
API Gateway と Function Compute の間の接続には形式要件があります。Function Compute が API Gateway に返す結果が指定された形式に従っていない場合、API Gateway はバックエンドサービスが利用不可であると判断します。形式要件の詳細については、「トリガーイベント形式」および「検証結果における Function Compute の戻りパラメーターの形式」をご参照ください。
応答の content-type をどのように設定すればよいですか?
図に示すように、API を構成する際に応答の content-type を設定できます。詳細については、「API Gateway を介した Function Compute 3.0(Web 関数)への接続」をご参照ください。
API Gateway トリガーが Function Compute 関数を実行します。関数は正常に動作しますが、一定期間呼び出されない場合、次の呼び出しで 503 エラーが報告されます。この原因は何でしょうか?
関数が一定期間呼び出されない場合、次の呼び出しのために実行環境を再度準備する必要があります。これによりコールドスタートの遅延が発生します。API Gateway で設定されたタイムアウト期間内に呼び出しが完了しない場合、API Gateway はバックエンドサービスが利用不可であると判断します。この問題を解決するには、API Gateway のタイムアウト期間を延長します。
API Gateway から関数に受信される body が Base64 エンコードされているのはなぜですか?
API Gateway は、FORM ベースの送信では body を Base64 エンコードしません。FORM 形式を使用するには、API Gateway で入力パラメーターのマッピングを選択する必要があります。その他の body 形式は、コンテンツの送信エラーまたは損失を防ぐために Base64 エンコードされます。まず、イベント内の isBase64 パラメーターが true であるかどうかを確認することを推奨します。isBase64 が true の場合、body は関数内でデコードする必要があります。API Gateway が Function Compute に渡すイベント形式の詳細については、「トリガーイベント形式」をご参照ください。