您可以使用Go請求處理常式響應接收到的事件並執行相應的商務邏輯。本文介紹Go請求處理常式的相關概念、結構特點和使用樣本。
如您需要通過HTTP觸發器或自訂網域名訪問函數,請先擷取請求結構體再自訂HTTP響應。更多資訊,請參見HTTP觸發器調用函數。
什麼是請求處理常式
FC函數的請求處理常式,是函數代碼中處理請求的方法。當您的FC函數被調用時,Function Compute會運行您提供的Handler方法處理請求。您可以通過Function Compute控制台的函數入口配置Handler。
對Go語言的FC函數而言,您的請求處理常式被編譯為一個可執行檔二進位檔案。您只需要將FC函數的請求處理常式配置項設定為該可執行檔的檔案名稱即可。
關於FC函數的具體定義和相關操作,請參見建立事件函數。
請求處理常式的具體配置均需符合Function Compute平台的配置規範。配置規範因請求處理常式類型而異。
使用樣本
在Go語言的代碼中,您需要引入官方的SDK庫aliyun/serverless/fc-runtime-go-sdk/fc
,並實現handler
函數和main
函數。樣本如下。
package main
import (
"fmt"
"context"
"github.com/aliyun/fc-runtime-go-sdk/fc"
)
type StructEvent struct {
Key string `json:"key"`
}
func HandleRequest(ctx context.Context, event StructEvent) (string, error) {
return fmt.Sprintf("hello, %s!", event.Key), nil
}
func main() {
fc.Start(HandleRequest)
}
傳入的event
參數是一個包含key
屬性的JSON字串,樣本如下。
{
"key": "value"
}
具體的樣本解析如下:
package main
:在Go語言中,Go應用程式都包含一個名為main
的包。import
:需要引用Function Compute依賴的包,主要包括以下包:github.com/aliyun/fc-runtime-go-sdk/fc
:Function ComputeGo語言的核心庫。context
:Function ComputeGo語言的Context對象。
func HandleRequest(ctx context.Context, event StructEvent) (string, error)
:處理請求的方法(即Handler),需包含將要執行的代碼,參數含義如下:func main()
:運行FC函數代碼的進入點,Go程式必須包含main
函數。通過添加代碼fc.Start(HandleRequest)
,您的程式即可運行在阿里雲Function Compute平台。
Event Handler簽名
下面列舉出了有效Event Handler簽名,其中InputType
和OutputType
與encoding/json
標準庫相容。
Function Compute會使用json.Unmarshal
方法對傳入的InputType
進行還原序列化,以及使用json.Marshal
方法對返回的OutputType
進行序列化。關於如何還原序列化函數的返回資料,請參考JSON Unmarshal。
func ()
func () error
func (InputType) error
func () (OutputType, error)
func (InputType) (OutputType, error)
func (context.Context) error
func (context.Context, InputType) error
func (context.Context) (OutputType, error)
func (context.Context, InputType) (OutputType, error)
Handler的使用需遵循以下規則:
Handler必須是一個函數。
Handler支援0~2個輸入參數。如果有2個參數,則第一個參數必須是
context.Context
。Handler支援0~2個傳回值。如果有1個傳回值,則必須是
error
類型;如果有2個傳回值,則第2個傳回值必須是error
。
函數的Handler範例程式碼:
event-struct.go:
event
為Struct類型的範例程式碼。event-string.go:
event
為String類型的範例程式碼。event-map.go:
event
為map[string]interface{}
類型的範例程式碼。
更多Handler樣本,請參見examples。
Context
Context的詳細使用方法,請參見上下文。
使用HTTP觸發器調用函數
範例程式碼
package main
import (
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"github.com/aliyun/fc-runtime-go-sdk/events"
"github.com/aliyun/fc-runtime-go-sdk/fc"
)
type HTTPTriggerEvent events.HTTPTriggerEvent
type HTTPTriggerResponse events.HTTPTriggerResponse
func (h HTTPTriggerEvent) String() string {
jsonBytes, err := json.MarshalIndent(h, "", " ")
if err != nil {
return ""
}
return string(jsonBytes)
}
func NewHTTPTriggerResponse(statusCode int) *HTTPTriggerResponse {
return &HTTPTriggerResponse{StatusCode: statusCode}
}
func (h *HTTPTriggerResponse) String() string {
jsonBytes, err := json.MarshalIndent(h, "", " ")
if err != nil {
return ""
}
return string(jsonBytes)
}
func (h *HTTPTriggerResponse) WithStatusCode(statusCode int) *HTTPTriggerResponse {
h.StatusCode = statusCode
return h
}
func (h *HTTPTriggerResponse) WithHeaders(headers map[string]string) *HTTPTriggerResponse {
h.Headers = headers
return h
}
func (h *HTTPTriggerResponse) WithIsBase64Encoded(isBase64Encoded bool) *HTTPTriggerResponse {
h.IsBase64Encoded = isBase64Encoded
return h
}
func (h *HTTPTriggerResponse) WithBody(body string) *HTTPTriggerResponse {
h.Body = body
return h
}
func HandleRequest(event HTTPTriggerEvent) (*HTTPTriggerResponse, error) {
fmt.Printf("event: %v\n", event)
if event.Body == nil {
return NewHTTPTriggerResponse(http.StatusBadRequest).
WithBody(fmt.Sprintf("the request did not come from an HTTP Trigger, event: %v", event)), nil
}
reqBody := *event.Body
if event.IsBase64Encoded != nil && *event.IsBase64Encoded {
decodedByte, err := base64.StdEncoding.DecodeString(*event.Body)
if err != nil {
return NewHTTPTriggerResponse(http.StatusBadRequest).
WithBody(fmt.Sprintf("HTTP Trigger body is not base64 encoded, err: %v", err)), nil
}
reqBody = string(decodedByte)
}
return NewHTTPTriggerResponse(http.StatusOK).WithBody(reqBody), nil
}
func main() {
fc.Start(HandleRequest)
}
上述樣本從SDK中引入了HTTP觸發器的請求結構HTTPTriggerEvent,以及響應結構HTTPTriggerResponse。關於HTTP觸發調用的請求負載格式和響應負載格式,請參見HTTP觸發器調用函數。
前提條件
已使用上述樣本建立運行環境為Go的函數,並建立HTTP觸發器。具體操作,請參見建立事件函數和配置HTTP觸發器並使用HTTP觸發。
操作步驟
登入Function Compute控制台,在左側導覽列,單擊函數。
在頂部功能表列,選擇地區,然後在函數頁面,單擊目標函數。
在函數詳情頁面,單擊配置頁簽,然後再左側導覽列,單擊觸發器,在觸發器頁面擷取HTTP觸發器的公網訪問地址。
執行以下命令調用函數。
curl -i "https://http-trigger-demo.cn-shanghai.fcapp.run" -d "Hello FC!"
錯誤處理
本範例程式碼支援使用HTTP Trigger觸發器或者自訂網域名調用,如果使用API調用,但配置的測試參數不符合HTTP Trigger請求格式規範,會出現報錯。
例如,在控制台上調用,配置請求參數為"Hello, FC!"
,點擊測試函數按鈕,會出現報錯如下所示。
{
"statusCode": 400,
"body": "the request did not come from an HTTP Trigger, event: {\n \"version\": null,\n \"rawPath\": null,\n \"headers\": null,\n \"queryParameters\": null,\n \"body\": null,\n \"isBase64Encoded\": null,\n \"requestContext\": null\n}"
}
如果想擷取原始的請求事件裝載,可以使用下面樣本中的Handler。
// GetRawRequestEvent: obtain the raw request event
func GetRawRequestEvent(event []byte) (*HTTPTriggerResponse, error) {
fmt.Printf("raw event: %s\n", string(event))
return NewHTTPTriggerResponse(http.StatusOK).WithBody(string(event)), nil
}
func main() {
fc.Start(GetRawRequestEvent)
}