Function Compute supports API Gateway as an event source. You can configure Function Compute as the backend service for an API. When a request reaches an API Gateway whose backend service is set to Function Compute, the associated function is triggered. Function Compute then returns the execution result to API Gateway.
Background information
API Gateway triggers are similar to HTTP triggers and can be used to build web applications. Compared with HTTP triggers, API Gateway enables advanced operations, such as configuring IP address whitelists or blacklists.
API Gateway supports both event functions and web functions as its backend service. After you connect API Gateway to Function Compute, you can securely expose functions through APIs and handle tasks such as authentication, traffic shaping, and data transformation.
Create an event function and connect it to API Gateway
Step 1: Create an event-triggered function
Create an event function in the Function Compute 3.0 console. For more information, see Create an event function.
Step 2: Create an API whose backend service is Function Compute
Define a backend service in API Gateway and configure its endpoint to connect to Function Compute.
Log on to the API Gateway console, select a region, and in the left navigation pane, choose Manage APIs > Backend Services. In the upper-right corner, click Create Backend Service. Configure the following information and click Confirm.

On the Backend Service page, click the backend service that you just created to go to the backend service definition page. Click the Production tab. In the Basic Information section, click Create. Select the event function that you created in Step 1 and then click Publish.

Create a group.
NoteCreate an API group in the same region as the function. If they are in different regions, the API must access your Function Compute service over the public network, which incurs traffic fees. If you have high requirements for data security and network latency, select the same region for the API and the function.
Create and publish the API.
Set the key configuration items as follows. Keep the default settings for the other items.

Configuration item
Example value
Security Authentication
No authentication
Configuration Mode
Use an existing backend service
Backend Service Type
Function Compute
Version
Function Compute 3.0
Function Type
Event function
Backend Services
Select the backend service for the event function that you just created.
Step 3: Write the function code
Log on to the Function Compute console. In the left-side navigation pane, click Functions.
In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.
On the function details page, click the Code tab. Write the code in the editor and then click Deploy.
The following sample code is provided for different languages:
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
When you use Java, you must implement a class that implements a predefined handler of Function Compute. You can implement one of the following two predefined handlers. For more information about the Java runtime of Function Compute, see Compile and deploy a code package.
(Recommended) Use the PojoRequestHandler<I, O> handler.
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 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. // Sample API response. Map headers = new HashMap(); boolean isBase64Encoded = false; int statusCode = 200; String returnBody = ""; return new ApiResponse(headers,isBase64Encoded,statusCode,returnBody); } }The two
POJOclasses,ApiRequestandApiResponse, are defined as follows.NoteThe
set()andget()methods of thePOJOclass must be complete.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; } }The pom.xml file is as follows.
<?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>
Use the StreamRequestHandler handler.
When you use this handler, you must convert the input
InputStreamto the correspondingPOJOclass. The following sample code is provided.The configuration of the pom.xml file is the same as that for the PojoRequestHandler<I, O> handler.
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 the InputStream to 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 process your own logic here. // Return structure. 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 must return the response 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; } } }
Step 4: Configure the input parameters for the function
When API Gateway triggers a function, it passes information as an event to the function's input parameters. You can use the event information from API Gateway as a parameter to test whether the function code is correct.
On the Code tab of the function details page, click the
icon next Test Function and select Configure Test Parameters from the drop-down list. In the Configure Test Parameters panel, select Create New Test Event or Modify Existing Test Event. Enter the event name and content, and then click OK.
The following example shows the event format:
{ "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" }The following table describes the fields in the event parameter.
Parameter
Type
Description
path
String
The path of the API request.
httpMethod
String
The name of the request method, such as GET, POST, PUT, or DELETE.
headers
Object
Contains all request header information, including system and custom headers.
queryParameters
Object
Query parameters, which typically appear as key-value pairs after the question mark (?) in a URL.
pathParameters
Object
Path parameters, which are typically part of a URL and used to identify a specific resource.
body
String
The request body.
isBase64Encoded
Boolean
Indicates whether the request body is Base64-encoded.
NoteIf the value of
isBase64Encodedistrue, the body content passed from API Gateway to Function Compute is Base64-encoded. Function Compute must Base64-decode the body content before processing it.If the value of
isBase64Encodedisfalse, API Gateway does not Base64-encode the body content. You can directly obtain the body content in the function.
Click Test Function.
Step 5: Verify the result
After the execution is complete, you can view the result above the Code tab.
Function Compute must return the execution result to API Gateway in the following JSON format. API Gateway then parses the result. The following example shows the response format:
{
"isBase64Encoded":true|false,
"statusCode":httpStatusCode,
"headers":{response headers},
"body":"..."
} Format requirements for connecting an event function to API Gateway
When API Gateway calls Function Compute, it converts API-related data into a map and passes it to the Function Compute service. After processing, Function Compute returns data such as statusCode, headers, and body in the specified output format. API Gateway then maps the content returned by Function Compute to the statusCode, headers, and body fields and returns it to the client.

Create a web function and connect it to API Gateway
Step 1: Create a web function
Create a web function in the Function Compute 3.0 console. For more information, see Create a web function.
By default, an HTTP trigger is created for the web function. Copy the internal network endpoint for later use.

Step 2: Create a backend service
Define a backend service in API Gateway and configure its endpoint to connect to Function Compute.
Log on to the API Gateway console, select a region, and in the left navigation pane, choose Manage APIs > Backend Services. In the upper-right corner, click Create Backend Service. Configure the following information and click Confirm.

On the Backend Service page, click the backend service that you just created to go to the backend service definition page. Click the Production tab. In the Basic Information section, click Create. Enter the internal network endpoint of the trigger for the web function that you created in Step 1 and then click Publish.

Step 3: Create and publish an API
Create an API to allow external applications to call the internal web function service in a specified way. Use API groups to organize and manage multiple related API operations, which simplifies the implementation of unified security policies and traffic shaping measures.
Log on to the API Gateway console. In the left navigation pane, choose Manage APIs > API Groups and click Create Group to manage APIs.
In the Create Group dialog box, select an Instances:, enter
FC-Groupfor Group Name, and set BasePath to/. Then, click Confirm.
NoteCreate an API group in the same region as the function. If they are in different regions, the API must access your Function Compute service over the public network, which incurs traffic fees. If you have high requirements for data security and network latency, select the same region for the API and the function.
On the group list page, find the target group, and in the Actions column, click Manage APIs. Then, click Create API, configure the following information, and click Next.

On the Define API Request configuration tab, set Request Path to
/, keep the default settings for other items, and click Next.On the Define Backend Service configuration tab, configure the settings as shown in the figure and click Next.

On the Define Response configuration tab, keep the default configurations and click Create. After the API is created, click Publish in the dialog box that appears.
In the Publish API dialog box, set the following configuration items and click Publish.

Step 4: Create an application and grant API authorization
An application (APP) serves as an identity when you call an API service. In Step 3: Create and publish an API, the authentication method was set to Alibaba Cloud APP. Therefore, after the API is published, you must create an APP and grant authorization to the APP to access the API.
Log on to the API Gateway console. In the left navigation pane, choose Call APIs > Apps.
On the Apps page, click Create App in the upper-right corner. On the Create App page, enter
fcAppfor App Name: and click Confirm.Click the name of the created
fcAppapplication to go to the App Details page. You can see that there are two authentication methods for an Alibaba Cloud APP:AppKeyandAppCode. TheAppKeymethod uses aAppKeyand anAppSecret. You can think of this as an account and password. When you call the API, theAppKeyis passed as a parameter, and theAppSecretis used for signature calculation. The gateway uses this key pair to authenticate your identity.
In the left navigation pane, choose Manage APIs > APIs. On the API List page, find the API that you created. In the Actions column, choose
> Authorize.On the authorization page, set Stage: to Production. Search for the
fcAppapplication that you created, click Add, and then click Confirm. A message indicates that the authorization is successful.
Step 5: Verify the result
This section describes how to use AppCode authentication to call the published API in your business system. A Curl command is used as an example.
Log on to the API Gateway console. In the left navigation pane, choose Call APIs > Apps. On the Apps page, find the authorized APP and click it to obtain the APPCode. Then, call the API as shown in the following example.
curl -i -X GET "http://fd6f8e2b7bf44ab181a56****-cn-hangzhou.alicloudapi.com" -H "Authorization:APPCODE 7d2b7e4945ce44028ab00***"FAQ
When an API Gateway trigger executes a function, a 502 error is reported. However, the function logs show that the function executed successfully. Why does this happen?
The connection between API Gateway and Function Compute has format requirements. If the result that Function Compute returns to API Gateway does not follow the specified format, API Gateway considers the backend service unavailable. For more information about the format requirements, see Trigger event format and the format of the return parameters from Function Compute in the verification result.
How do I set the content-type of the response?
As shown in the figure, you can set the content-type of the response when you configure the API. For more information, see Connect to Function Compute 3.0 (web function) through API Gateway.
An API Gateway trigger executes a Function Compute function. The function works correctly, but if it is not called for a period, the next call reports a 503 error. What is the reason for this?
If a function is not called for a period, the execution environment must be prepared again for the next call. This causes a cold start delay. If the call is not completed within the timeout period set in API Gateway, API Gateway considers the backend service unavailable. To resolve this issue, extend the timeout period in API Gateway.
Why is the body received by the function from API Gateway Base64-encoded?
API Gateway does not Base64-encode the body for FORM-based transmissions. To use the FORM format, you must select input parameter mapping in API Gateway. Other body formats are Base64-encoded to prevent content transmission errors or loss. We recommend that you first check whether the isBase64 parameter in the event is true. If isBase64 is true, the body must be decoded in the function. For more information about the event format that API Gateway passes to Function Compute, see Trigger event format.