本文介紹Custom Container中函數調用的方式、使用限制及程式碼範例。
背景資訊
Custom Container支援託管使用者的HTTP Server,並將函數調用的請求轉換為HTTP請求發送到HTTP Server,將HTTP Server的響應轉換為函數調用的響應返回給Client。過程示意如下:
函數調用的方式有兩種,分別為:
HTTP調用(推薦):使用HTTP方式調用,例如使用HTTP觸發器或者自訂網域名來調用。
API調用:通過InvokeFunction API進行調用,例如使用SDK調用函數或者通過事件來源觸發函數。
調用方式的不同,使用者的HTTP Server的請求和響應的格式也會不同。
使用限制
HTTP Request限制
Request Headers不支援以x-fc-開頭的自訂欄位和以下自訂欄位:
connection
keep-alive
如果Request超過以下限制,會返回
400
狀態代碼和InvalidArgument
錯誤碼。Headers大小:Headers中的所有Key和Value的總大小不得超過8 KB。
Path大小:包括所有的Query Params,Path的總大小不得超過4 KB。
Body大小:同步調用請求的Body的總大小不得超過32 MB,非同步呼叫請求的Body的總大小不得超過128 KB。
HTTP Response限制
Response Headers不支援以x-fc-開頭的自訂欄位和以下自訂欄位:
connection
content-length
date
keep-alive
server
content-disposition:attachment
說明從安全形度考慮,使用Function Compute預設的aliyuncs.com網域名稱,服務端會在Response Headers中強制添加content-disposition: attachment欄位,此欄位會使得返回結果在瀏覽器中以附件的方式下載。如果需要解除該限制,需設定自訂網域名。更多資訊,請參見配置自訂網域名。
如果Response超過以下限制,會返回
502
狀態代碼和BadResponse
錯誤碼。Headers大小:Headers中的所有Key和Value的總大小不得超過8 KB。
其他使用說明
您可以通過綁定自訂網域名,為函數映射不同的HTTP訪問路徑。詳細資料,請參見配置自訂網域名。
HTTP調用(推薦)
對於HTTP方式的調用,Function Compute採用透傳模式,即將Client的HTTP請求透傳到使用者的HTTP Server,並且將HTTP Server的響應透傳給Client。一些系統保留的欄位將不會透傳,具體請參考使用限制。
要求標頭(HTTP Request Header)
使用HTTP觸發器或者自訂網域名調用函數時,Function Compute支援使用配置要求標頭控制請求的行為,具體如下表所示。
名稱 | 類型 | 是否必選 | 樣本 | 描述 |
X-Fc-Invocation-Type | String | 否 | Sync | 調用方式,具體資訊請參見調用方式。取值說明如下:
|
X-Fc-Log-Type | String | 否 | Tail | 請求返回日誌。取值說明如下:
|
回應標頭(HTTP Response Header)
使用HTTP觸發器或自訂網域名調用函數時,響應中會包含Function Compute預設添加的一些回應標頭,具體如下表所示。
名稱 | 描述 | 樣本值 |
X-Fc-Request-Id | 函數調用的請求ID。 | dab25e58-9356-4e3f-97d6-f044c4**** |
API調用
對於使用InvokeFunction API的調用,Function Compute會將InvokeFunction請求轉換成HTTP請求,傳遞給使用者的HTTP Server,轉換的規則如下:
InvokeFunction的event參數被轉換成HTTP請求的訊息體。
path
為/invoke
。method
為POST
。Content-Type
訊息頭為application/octe-stream
。
Function Compute會將使用者HTTP Server的響應轉換為InvokeFunction的響應返回給用戶端,轉換的規則如下:
HTTP響應體轉換成InvokeFunction的響應體。
在轉換過程中會丟失HTTP回應標頭和狀態代碼資訊。
Invoke API 請求的轉換樣本
Invoke請求 | HTTP Request (HTTP Server收到的請求) |
Invoke API 請求內容:
|
|
Invoke API 響應的輸出樣本
HTTP Response | Invoke響應 |
|
|
|
|
程式碼範例
您可以使用任意語言實現HTTP Server。本文以Python為例,程式碼範例如下。
import os
from flask import Flask
from flask import request
REQUEST_ID_HEADER = 'x-fc-request-id'
app = Flask(__name__)
@app.route('/', defaults={'path': ''})
@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
def hello_world(path):
rid = request.headers.get(REQUEST_ID_HEADER)
data = request.stream.read()
print("Path: " + path)
print("Data: " + str(data))
return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9000)
樣本解析如下:
@app.route('/', defaults={'path': ''})
:預設路由,對應根路徑。@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
:帶有路徑參數的動態路由,可以處理GET、POST、PUT、DELETE請求。路徑參數的值將被傳遞給hello_world函數作為參數path。rid = request.headers.get(REQUEST_ID_HEADER)
:擷取要求標頭中的x-fc-request-id
欄位的值。data = request.stream.read()
:讀取請求的內容,並將其賦值給變數data。return "Hello, World!", 200, [('Function-Name', os.getenv('FC_FUNCTION_NAME'))]
:返回一個包含"Hello, World!"的響應體,並設定狀態代碼為200及一個包含Function-Name
頭部的元組。