API Gateway triggers

Updated at: 2025-03-05 10:12

Function Compute supports using API Gateway as an event source. You can configure Function Compute as the backend service for APIs. When a request is received by the API Gateway instance configured to use Function Compute as its backend service, API Gateway triggers the associated function to execute. Once the function completes its execution, Function Compute sends the result back to API Gateway.

Background

API Gateway triggers work similarly to HTTP triggers and can be used to build web applications. Unlike HTTP triggers, API Gateway triggers allow you to perform advanced operations, such as setting IP whitelists or blacklists.

API Gateway can be configured to use both event functions and web functions as its backend service. Once Function Compute is integrated with API Gateway, these functions can be securely exposed to clients through APIs. This setup allows for effective management of various concerns, including authentication, traffic control, and data conversion.

Create an event function and integrate it with API Gateway

Step 1: Create an event function

Create an event function in the Function Compute console. For more information, see Create an event function.

Step 2: Create an API with Function Compute as its backend service

You must create a backend service in API Gateway and configure a URL for the backend service to point to your Function Compute service.

  1. Log on to the API Gateway console. In the left-side navigation pane, choose Manage APIs > Backend Services. In the top navigation bar, select a region. Then, click Create Backend Service in the upper-right corner, configure the parameters as shown in the following figure, and click Confirm:

    image

  2. On the Backend Services page, click the backend service you just created. On the Backend Service Definition page, click the Production tab. In the Basic Information section, click Create. Choose the event function you created in Step 1 and click Publish.

    image

  3. Create an API group.

    Note

    We recommend that you create an API group in the same region as your function. If the API is in a different region, it will need to access your Function Compute services over the Internet, which will incur traffic costs. For stringent data security and network latency requirements, ensure that the API group is created in the same region as your function.

  4. Create and publish an API.

    Configure the required parameters as outlined below. You can leave the rest at their default settings.

    image

    Parameter

    Configuration instruction

    Parameter

    Configuration instruction

    Security Authentication

    Select No Authentication.

    Configuration Mode

    Choose Use Existing Backend Service.

    Backend Service Type

    Choose Function Compute.

    Version

    Choose Function Compute V3.0.

    Function Type

    Choose Event Function.

    Backend Service

    Choose the backend service you just created that points to the event function.

Step 3: Write the function code

  1. Log on to the Function Compute console. In the left-side navigation pane, click Functions.

  2. In the top navigation bar, select a region. On the Functions page, click the function that you want to manage.

  3. On the Code tab of the Function Details page, write code in the code editor and click Deploy.

    The sample code for different languages is as follows:

    Node.js
    Python
    PHP
    Java
    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)
    };                               
    # -*- 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
    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);
    } 

    When you program in Java for Function Compute, you must implement a class that uses a predefined handler method. There are two predefined handler methods. For more information about the Java runtime, see Compile and deploy code packages.

    • (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 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);
          }
      }                                        
      • The following sample defines two POJO classes: ApiRequest and ApiResponse.

        Note

        The set() and get() methods of the POJO classes must be specified.

        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 following code shows an example of the pom.xml file.

        <?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.

      To use this handler, you must convert InputStream to the POJO class. The following sample code describes how to use this handler.

      The configuration of the pom.xml file is the same as when using 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 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 write your own logic here. 
      
                  // The returned result. 
                  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;
              }
          }
      }                                        

Step 4: Configure the input parameter of the function

When API Gateway triggers a function, it passes information in the form of an event object into the function. You can use the information to debug your function.

  1. On the Code tab of the function details page, click the image.png icon next Test Function and select Configure Test Parameters from the drop-down list.

  2. In the Configure Test Parameters panel, click the Create New Test Event or Modify Existing Test Event tab, enter the event name and event content, and click OK.

    An example of the event object is as follows:

    {
        "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 parameters in an event object.

    Parameter

    Type

    Description

    Parameter

    Type

    Description

    path

    String

    The API request path.

    httpMethod

    String

    The request method. Valid values: GET, POST, PUT, and DELETE.

    headers

    Object

    The request header information. It encompasses all request headers, including both system headers and custom headers.

    queryParameters

    Object

    The query parameters. They are usually in the form of key-value pairs that appear after the question mark in the URL.

    pathParameters

    Object

    The path parameters. They are usually part of the URL and are used to identify specific resources.

    body

    String

    The request body.

    isBase64Encoded

    Boolean

    Specifies whether the request body is in Base64 encoding.

    Note
    • If the value of isBase64Encoded is true, the body content that API Gateway sends to Function Compute is Base64-encoded. Function Compute decodes the body content from Base64 format before processing the content.

    • If the value of isBase64Encoded is false, API Gateway did not perform Base64 encoding on the body content, and Function Compute can directly obtain the body content.

  3. Click Test Function.

Step 5: View the result

After the function is executed, you can view the result on the Code tab.

Function Compute sends the execution result to API Gateway for parsing in the following JSON format. The following code snippet shows an example of the returned result:

{
    "isBase64Encoded":true|false,
    "statusCode":httpStatusCode,
    "headers":{response headers},
    "body":"..."
}       

Format requirements when an event function is integrated with API Gateway

After API Gateway receives a request for an API operation with Function Compute as the backend service, API Gateway converts the request parameters to key-value pairs in the map format and sends the request to Function Compute. Function Compute handles the request and returns a response in a specific output format to API Gateway. The response includes information such as the status code, header, and body, as shown in the following figure. API Gateway maps the information in the response that is returned by Function Compute to the status code, headers, and body of an API response, and returns the API response to the client.

principle

Create a web function and integrate it with API Gateway

Step 1: Create a web function

Create a web function in the Function Compute console. For more information, see Step 1: Create a web function.

An HTTP trigger is automatically created for the web function you just created. Copy the internal endpoint for subsequent use.

image

Step 2: Create a backend service

You must create a backend service in API Gateway and configure a URL for the backend service to point to your Function Compute service.

  1. Log on to the API Gateway console. In the left-side navigation pane, choose Manage APIs > Backend Services. In the top navigation bar, select a region. Then, click Create Backend Service in the upper-right corner, configure the parameters as shown in the following figure, and click Confirm:

    image

  2. On the Backend Services page, click the backend service you just created. On the Backend Service Definition page, click the Production tab. In the Basic Information section, click Create. Paste the internal endpoint you copied in Step 1 and click Publish.

    image

Step 3: Create and publish an API

In this step, you create an API that allows external applications to call internal web functions in specific ways. API groups are used to organize and manage multiple related APIs, facilitating the implementation of unified security policies and traffic control measures.

  1. Log on to the API Gateway console. In the left-side navigation pane, choose Manage APIs > API Groups. On the API Groups page, click Create Group.

  2. In the Create Group dialog box, select an instance from the Instances drop-down list, set the Group Name parameter to FC-Group and the BasePath parameter to /, and click Confirm.

    image

    Note

    We recommend that you create an API group in the same region as your function. If the API is in a different region, it will need to access your Function Compute services over the Internet, which will incur traffic costs. For stringent data security and network latency requirements, ensure that the API group is created in the same region as your function.

  3. On the API Groups page, find the API group that you created, click Manage APIs in the Actions column, and then click Create API. Configure the following parameters and click Next.

    image

  4. In the Define API Request step, set the Request Path parameter to /, use the default values for other parameters, and then click Next.

  5. In the Define Backend Service step, configure the following parameters and click Next:

    image

  6. In the Define Response step, keep the default settings and click Create. In the Note dialog box that appears, click Publish.

  7. In the Publish API dialog box, configure the following parameters and click Publish.

    image

Step 4: Create an application and authorize it to call the API

The application represents the identity that is used to authenticate when making requests to the API service. In this example, Alibaba Cloud App was selected for the Security Authentication parameter in Step 3: Create and publish an API. Therefore, after the API is published, you must create an application and authorize it to call the API.

  1. Log on to the API Gateway console. In the left-side navigation pane, choose Call APIs > Apps.

  2. On the Apps page, click Create App in the upper-right corner. In the Create App dialog box, set App Name to fcApp and click Confirm.

  3. On the Apps page, click the fcApp application you just created. On the App Details page, you can see that two authentication methods are available: AppKey and AppCode. The AppKey method includes a pair of AppKey and AppSecret, which works similarly to a pair of username and password. When you call the API, you must pass the AppKey as a parameter. The AppSecret is used to calculate signatures. API Gateway verifies the AppKey-AppSecret pair to authenticate your identity.

    image

  4. In the left-side navigation pane, choose Manage APIs > APIs. On the APIs page, find the API you just created and click image > Authorize in the Actions column.

  5. In the Authorize dialog box, set the Stage parameter to Production. Enter fcApp in the search bar of the Choose Apps for Authorization section. In the search results, select the fcApp application, click Add in the Actions column, and then click Confirm. A message appears to inform you that the application is authorized to call the API.

    image

Step 5: Verify the result

The following section describes how to use the AppCode-based authentication method to call a published API in your business system. This example uses Curl commands to make the API calls.

Log on to the API Gateway console. In the left-side navigation pane, choose Call APIs > Apps. On the Apps page, click the authorized application and obtain its AppCode on the page that appears. Then, use the following sample code to call the API:

curl -i -X GET "http://fd6f8e2b7bf44ab181a56****-cn-hangzhou.alicloudapi.com" -H "Authorization:APPCODE 7d2b7e4945ce44028ab00***"

FAQ

Error code 502 is returned when function execution is triggered by API Gateway, but the function log shows that the function is successfully executed. How do I resolve this issue?

API Gateway requires Function Compute to return responses in a specific format. If the response is not in the expected format, API Gateway considers the backend service unavailable. For more information about the format requirements of the integration between API Gateway and Function Compute, see Formats of event for different triggers and Step 5: View the result.

How do I set the content type of the returned response?

As shown in the following figure, you can specify the content type of a response in the Define Response step when you create the API. For more information, see Use API Gateway to trigger a web function in Function Compute 3.0.content-type

Error code 503 is returned when I use API Gateway to invoke a function that was previously invoked but has not been invoked for a period of time. How do I resolve this issue?

If a function has not been invoked for some time, a new execution environment must be prepared upon its next invocation, resulting in a cold start delay. This can cause a timeout in API Gateway before the invocation completes, leading API Gateway to treat the backend service as unavailable. To resolve this issue, increase the API Gateway timeout period.

Why is the body parameter of the requests passed from API Gateway to Function Compute Base64-encoded?

The body of requests is Base64-encoded to prevent content transmission errors or loss, except for bodies transmitted in form format by API Gateway, which are not Base64-encoded. When using form format, you must select Input Parameter Mapping in API Gateway. We recommend that you check whether the value of isBase64 is true or false. If the value of isBase64 is true, Function Compute decodes the body content from Base64 format before processing the content. For more information about the event format that is passed to Function Compute by API Gateway, see Formats of event for different triggers.

  • On this page (1, M)
  • Background
  • Create an event function and integrate it with API Gateway
  • Step 1: Create an event function
  • Step 2: Create an API with Function Compute as its backend service
  • Step 3: Write the function code
  • Step 4: Configure the input parameter of the function
  • Step 5: View the result
  • Format requirements when an event function is integrated with API Gateway
  • Create a web function and integrate it with API Gateway
  • Step 1: Create a web function
  • Step 2: Create a backend service
  • Step 3: Create and publish an API
  • Step 4: Create an application and authorize it to call the API
  • Step 5: Verify the result
  • FAQ
Feedback