全部產品
Search
文件中心

API Gateway:Function Compute

更新時間:Jul 13, 2024

Function Compute是一個事件驅動的服務(函數概述)。API Gateway與Function Compute對接,可以讓您以 API 形式安全地對外開放您的函數,並且解決認證、流量控制、資料轉換等問題。

1 功能簡介

API Gateway目前支援兩種形式的函數,HTTP函數事件函數

2 HTTP函數對接API Gateway

2.1 建立HTTP函數

在配置API Gateway前,需要先在Function Compute中建立一個帶有HTTP觸發器的函數,可參考配置HTTP觸發器並使用HTTP觸發

2.2 添加API

說明

在API Gateway控制台上的詳細操作步驟,詳見快速入門中的 建立後端為Function Compute的API。本文主要對需要注意的地方加以說明。

  • API分組。建議API分組與Function Compute在相同的地區。

說明

如果Function Compute與 API 不在同一地區,將通過公網訪問您的Function Compute服務,產生流量費用。若您對資料安全和網路延遲有較高要求,請選擇API 與Function Compute為同一地區。

  • 建立和定義API。在“定義API後端服務”步驟中,如下圖所示:

後端服務類型:選擇“Function Compute”。

調用方式:選擇“HTTP觸發器”。

觸發器路徑:請使用Function Compute控制台觸發器頁面中的路徑;如果是同region調用,可以將觸發器路徑上的網域名稱更換為內網地址。在Function Compute控制台左側欄單擊服務及函數——單擊服務名稱進入——在函數管理中找到HTTP函數——單擊函數名稱,在觸發器管理(URL) 裡面找到內網訪問地址。

後端請求path:可以自訂path,如果不需要自訂,請填寫"/"。

HTTP Method:請選擇後端Function Compute支援的method, 如果多個請選擇"any".

角色Arn:用於授權API Gateway訪問Function Compute服務。預設情況下,您需要按照API Gateway控制台上的操作引導,即可實現API Gateway訪問相同帳號下的Function Compute。

2.3 使用其他帳號的Function Compute

API Gateway除了使用相同帳號下的Function Compute服務外,還可以使用其他帳號下的Function Compute服務。以A帳號下的API Gateway需要使用B帳號下的Function Compute為例,介紹如何操作。

  1. B帳號為A帳號API Gateway的訪問Function Compute授權

    步驟1:使用B帳號登入RAM控制台,建立RAM角色,參考建立可信實體為阿里雲帳號的RAM角色

    步驟2:為步驟1中建立的角色增加調用Function Compute的授權。需要添加名為AliyunFCInvocationAccess的系統許可權,參考在RAM角色管理頁面為RAM角色授權

    步驟3:修改步驟1建立的角色的信任策略,參考 修改RAM角色的可信實體為阿里雲帳號。將A帳號的AccountID(如123456789012****)添加到信任策略中,修改後的信任策略如下:

{
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "123456789012****@apigateway.aliyuncs.com"
        ]
      }
    }
  ],
  "Version": "1"
}

步驟4:B帳號將步驟1建立的角色的Arn(瞭解 RAM角色基本概念)提供給A帳號。

  1. A帳號在API Gateway控制台中添加訪問B帳號的Function Compute服務。其中觸發路徑內容為B帳號下的Function Compute服務的訪問地址,角色Arn中填寫B帳號提供的角色Arn名稱。

重要

當後端服務為HTTP函數時,用戶端發送的Authorization參數值會被HTTP函數的Authorization覆蓋,建議用戶端更換參數名稱。

3 事件函數對接API Gateway

3.1 建立事件觸發函數

Function Compute控制台配置API Gateway觸發函數執行的流程可以參考配置API Gateway觸發器

3.2 建立API

說明

在API Gateway控制台上的詳細操作步驟,詳見快速入門中的 建立後端為Function Compute的API。本文主要對需要注意的地方加以說明。

  • API分組。建議API分組與Function Compute在相同的地區。

說明

如果Function Compute與 API 不在同一地區,將通過公網訪問您的Function Compute服務,產生流量費用。若您對資料安全和網路延遲有較高要求,請選擇API 與Function Compute為同一地區。

  • 建立API。在“定義API後端服務”步驟中,如下圖所示:

image

函數類型:選擇“事件”

服務名稱函數名稱:請根據實際的Function Compute名稱填寫。

3.2.事件函數對接API Gateway的格式要求

API Gateway調用Function Compute的事件函數時,會將 API 的相關資料轉換為 Map 形式傳給Function Compute服務。Function Compute服務處理後,按照下圖中 Output Format 的格式返回 statusCode、headers、body 等相關資料。API Gateway再將Function Compute返回的內容映射到 statusCode、header、body等位置返回給用戶端。

API Gateway向Function Compute傳入參數格式:

當以Function Compute作為 API Gateway的後端服務時,API Gateway會把請求參數通過一個固定的 Map 結構傳給Function Compute的入參 event。Function Compute通過如下結構去擷取需要的參數,然後進行處理。

{
        "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 內容已進行 Base 64 編碼。Function Compute需要先對 body 內容進行 Base64 解碼後再處理。

  • 如果"isBase64Encoded" 的值為 "false",表示 API Gateway沒有對 body 內容進行 Base 64 編碼。

Function Compute的返回參數格式:

Function Compute需要將輸出內容通過如下 JSON 格式返回給 API Gateway,以便 API Gateway解析。

{
        "isBase64Encoded":true|false,
        "statusCode":httpStatusCode,
        "headers":{response headers},
        "body":"..."
}
  • 當 body 內容為二進位編碼時,需在Function Compute中對 body 內容進行 Base 64 編碼,設定"isBase64Encoded" 的值為 "true"。如果 body 內容無需 Base 64 編碼,"isBase64Encoded" 的值為 "false"。API Gateway會對 "isBase64Encoded" 的值為 "true" 的 body 內容進行 Base64 解碼後,再返回給用戶端。

  • 在 Node.js 環境中,Function Compute根據不同的情況設定 callback。

    • 返回成功請求: callback(null,{"statusCode":200,"body":"..."})。

    • 返回異常:callback(new Error('internal server error'),null)。

    • 返回用戶端錯誤: callback(null,{"statusCode":400,"body":"param error"})。

  • 如果Function Compute返回不符合格式要求的返回結果,API Gateway將返回 503 Service Unavailable 給用戶端。

3.3 事件函數調用樣本

以下提供三個樣本,分別為:事件函數程式碼範例、API 請求樣本、和 API Gateway返回樣本。

3.3.1 事件函數程式碼範例

在Function Compute的代碼執行頁面配置的程式碼範例。

module.exports.handler = function(event, context, callback) {
    var responseCode = 200;
    console.log("request: " + JSON.stringify(event.toString()));
    //將event轉化為JSON對象
    event=JSON.parse(event.toString());
    var isBase64Encoded=false;
        //根據使用者輸入的statusCode返回,可用於測試不同statusCode的情況
    if (event.queryParameters !== null && event.queryParameters !== undefined) {
        if (event.queryParameters.httpStatus !== undefined && event.queryParameters.httpStatus !== null && event.queryParameters.httpStatus !== "") {
            console.log("Received http status: " + event.queryParameters.httpStatus);
            responseCode = event.queryParameters.httpStatus;
        }
    }
    //如果body是Base64編碼的,FC中需要對body內容進行解碼
    if(event.body!==null&&event.body!==undefined){
            if(event.isBase64Encoded!==null&&event.isBase64Encoded!==undefined&&event.isBase64Encoded){
                    event.body=new Buffer(event.body,'base64').toString();
            }
    }
    //input是API Gateway給FC的輸入內容
    var responseBody = {
        message: "Hello World!",
        input: event
    };
        //對body內容進行Base64編碼,可根據需要處理
    var base64EncodeStr=new Buffer(JSON.stringify(responseBody)).toString('base64');
        //FC給API Gateway返回的格式,須如下所示。isBase64Encoded根據body是否Base64編碼情況設定
    var response = {
                isBase64Encoded:true,
                statusCode: responseCode,
                headers: {
                "x-custom-header" : "header value"
                },
                body: base64EncodeStr
    };
    console.log("response: " + JSON.stringify(response));
    callback(null, response);
};        

3.3.2 事件函數請求樣本

以 POST 形式請求 path 為如下的 API:

/fc/test/invoke/[type]        

發起請求如下:

POST http://test.alicloudapi.com/fc/test/invoke/test?param1=aaa&param2=bbb
"X-Ca-Signature-Headers":"X-Ca-Timestamp,X-Ca-Version,X-Ca-Key,X-Ca-Stage",
"X-Ca-Signature":"TnoBldxxRHrFferGlzzkGcQsaezK+ZzySloKqCOsv2U=",
"X-Ca-Stage":"RELEASE",
"X-Ca-Timestamp":"1496652763510",
"Content-Type":"application/x-www-form-urlencoded; charset=utf-8",
"X-Ca-Version":"1",
"User-Agent":"Apache-HttpClient\/4.1.2 (java 1.6)",
"Host":"test.alicloudapi.com",
"X-Ca-Key":"testKey",
"Date":"Mon, 05 Jun 2017 08:52:43 GMT","Accept":"application/json",
"headerParam":"testHeader"
{"bodyParam":"testBody"}        

3.3.3 API Gateway返回樣本

200
Date: Mon, 05 Jun 2017 08:52:43 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 429
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,HEAD,OPTIONS , PATCH
Access-Control-Allow-Headers: X-Requested-With, X-Sequence,X-Ca-Key,X-Ca-Secret,X-Ca-Version,X-Ca-Timestamp,X-Ca-Nonce,X-Ca-API-Key,X-Ca-Stage,X-Ca-Client-DeviceId,X-Ca-Client-AppId,X-Ca-Signature,X-Ca-Signature-Headers,X-Forwarded-For,X-Ca-Date,X-Ca-Request-Mode,Authorization,Content-Type,Accept,Accept-Ranges,Cache-Control,Range,Content-MD5
Access-Control-Max-Age: 172800
X-Ca-Request-Id: 16E9D4B5-3A1C-445A-BEF1-4AD8E31434EC
x-custom-header: header value
{"message":"Hello World!","input":{"body":"{\"bodyParam\":\"testBody\"}","headers":{"X-Ca-Api-Gateway":"16E9D4B5-3A1C-445A-BEF1-4AD8E31434EC","headerParam":"testHeader","X-Forwarded-For":"100.81.146.152","Content-Type":"application/x-www-form-urlencoded; charset=UTF-8"},"httpMethod":"POST","isBase64Encoded":false,"path":"/fc/test/invoke/test","pathParameters":{"type":"test"},"queryParameters":{"param1":"aaa","param2":"bbb"}}}
        

4 常見問題

4.1 為什麼我無法錄入我已有的函數?

請確認您輸入的Function Compute的服務名稱和函數名稱是否與您在Function Compute控制台建立的服務和函數的名稱一致。

4.2 使用Function Compute作為API後端服務時,API Gateway到後端服務是否可以走內網?

當選擇事件函數時,API Gateway和Function Compute在同一region時,預設走內網。