Function Computeは、イベントソースとしてAPI Gatewayをサポートしています。 APIのバックエンドサービスとしてFunction Computeを指定できます。 リクエストのバックエンドサービスとしてFunction Computeを指定した場合、API Gatewayは関連付けられた関数をトリガーし、関数は1回実行されます。 Function Computeは、実行結果をAPI Gatewayに返します。 このトピックでは、function Computeコンソールで関数の実行をトリガーするAPI Gatewayを設定する方法について説明します。入力パラメーターの設定、関数コードの記述、関数のテストなどがあります。
前提条件
Function Compute
APIゲートウェイ
ステップ1: 関数の入力パラメータを設定する
API Gatewayが関数をトリガーすると、API Gatewayからの情報がイベントの形式で入力パラメーターとして関数に送信されます。 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" }
説明isBase64Encoded
の値がtrue
の場合、API GatewayがFunction Computeに送信するbodyコンテンツはBase64-encodedです。 Function Computeは、コンテンツが処理される前に、Base64形式からbodyコンテンツをデコードします。isBase64Encoded
の値がfalse
の場合、API Gatewayはbodyコンテンツに対してBase64エンコードを実行しません。 Function Computeは、bodyコンテンツを直接取得できます。
ステップ2: 関数コードを記述し、関数をテストする
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 // You can write your own logic here. } 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'] } # You can write your own logic here. 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) { // Obtain the API request information. 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); // You can write your own logic here. // API response example. Map headers = new HashMap(); boolean isBase64Encoded = false; int statusCode = 200; String returnBody = ""; return new ApiResponse(headers,isBase64Encoded,statusCode,returnBody); } }
次のサンプルでは、
ApiRequest
とApiResponse
の2つのPOJO
クラスを定義します。説明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 { // Convert InputStream into a string. 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))); // You can modify your own logic here. // Response parameters 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 returns responses to API Gateway in the following JSON format. 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; } } }
コードタブをクリックし、テスト機能をクリックします。
ステップ3: 結果を確認する
関数の実行後、[コード] タブで結果を表示できます。
Function Computeは、次のJSON形式で解析するために実行結果をAPI Gatewayに送信します。 次のコードは、応答の例を示しています:
{
"isBase64Encoded":true|false,
"statusCode":httpStatusCode,
"headers":{response headers},
"body":"..."
}
Function ComputeからAPI Gatewayに返された結果がフォーマット要件を満たしていない場合、API Gatewayは503 Service Unavailableエラーを返します。
bodyパラメーターのコンテンツがバイナリ形式の場合、Base64でコンテンツをエンコードする必要があります。 Base64でコンテンツをエンコードするには、isBase64Encodedをtrueに設定する必要があります。 bodyパラメーターの内容がバイナリ形式でない場合、Base64でコンテンツをエンコードする必要はありません。 この場合、isBase64Encodedをfalseに設定する必要があります。
よくある質問
関数の実行がAPI Gatewayによってトリガーされたが、関数が実行されたことが関数ログに示された場合、エラーコード503が返されます。 この問題を解決するにはどうすればよいですか?
API Gatewayでは、Function Computeが特定の形式で応答を返す必要があります。 返された結果が期待された形式でない場合、API Gatewayはバックエンドサービスを利用できないと見なします。 API GatewayとFunction Compute間の接続の形式要件の詳細については、「さまざまなトリガーに対するイベントの形式」および「Function Computeの応答の形式」をご参照ください。
返されたレスポンスのコンテンツタイプを設定するにはどうすればよいですか?
図に示すように、API操作を設定すると、レスポンスのコンテンツタイプを指定できます。 詳細については、「Function Computeをバックエンドサービスとして使用したAPI操作の作成」をご参照ください。
API Gatewayを使用して、以前に呼び出されたが一定期間呼び出されていない関数を呼び出すと、エラーコード503が返されます。 この問題を解決するにはどうすればよいですか?
関数が一定期間呼び出されていない場合、関数が再び呼び出されてコールドスタート遅延が発生したときに、新しい実行環境を準備する必要があります。 このようにして、呼び出しが完了する前にAPI Gatewayでタイムアウトが発生します。 API Gatewayは、バックエンドサービスを利用できないと見なします。 この問題を解決するには、API Gatewayのタイムアウト期間をより大きな値に設定します。
API GatewayからFunction Compute Base64-encodedに渡されるリクエストのbodyパラメーターはなぜですか。
要求の本体パラメータは、コンテンツ伝送エラーまたは損失を防止するためにBase64-encodedされる。 API Gatewayによって送信されるフォーム形式のボディはBase64-encodedされません。 ボディをフォーム形式で送信する場合は、API Gatewayで [入力パラメーターマッピング] を選択する必要があります。 関数でイベントをデコードする前に、isBase64 in eventの値がtrueかどうかを確認することを推奨します。 isBase64がtrueに設定されている場合、リクエストボディをデコードする必要があります。 API GatewayによってFunction Computeに渡されるイベントの形式の詳細については、「さまざまなトリガーに対するイベントの形式」をご参照ください。
追加情報
Function Computeコンソールに加えて、次の方法を使用してトリガーを設定できます。
Serverless Devsを使用してトリガーを設定します。 詳細については、「Serverless Devs」をご参照ください。
SDKを使用してトリガーを設定します。 詳細は、SDK をご参照ください。
作成したトリガーを変更または削除するには、「トリガーの管理」をご参照ください。