Goハンドラーを使用して、受信したイベントに応答し、対応するビジネスロジックを実行できます。 このトピックでは、Goハンドラーの概念と構造について説明し、例を示します。
HTTPトリガーまたはカスタムドメイン名を使用して関数にアクセスする場合は、HTTP応答を定義する前にリクエスト構造体を取得してください。 詳細については、「HTTPトリガーを使用した関数の呼び出し」をご参照ください。
ハンドラーとは何ですか?
Function Computeの関数のハンドラーは、関数コードでリクエストを処理するために使用されるメソッドです。 関数が呼び出されると、Function Computeは設定したハンドラーを使用してリクエストを処理します。 Function Computeコンソールでhandlerパラメーターを指定することで、ハンドラーを設定できます。
Function ComputeのGo関数のハンドラは、実行可能なバイナリファイルにコンパイルされます。 Function Computeの関数のハンドラーを実行可能ファイルの名前に設定するだけです。
Function Compute関数と関連する操作の詳細については、「イベント関数の作成」をご参照ください。
ハンドラーの設定は、Function Computeの設定仕様に準拠している必要があります。 設定の仕様は、ハンドラーの種類によって異なります。
例:
Goコードでは、公式のSDKライブラリaliyun/serverless/fc-runtime-go-sdk/fc
を導入し、ハンドラー
と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)
}
input event
の値は、key
プロパティを含むJSON文字列です。 次のサンプルコードに例を示します。
{
"key": "value"
}
パラメーターの説明:
パッケージメイン
:メイン
パッケージ。 各Goアプリケーションにはメインパッケージが含まれています。import
: Function Computeの依存関係をインポートします。 次の依存関係をインポートする必要があります。github.com/aliyun/fc-runtime-go-sdk/fc
: Function ComputeのGoのコアライブラリcontext
: Function ComputeのGoコンテキストオブジェクト。
func HandleRequest(ctx context.Context, event StructEvent) (string, error)
: 実行するコードを含む必要があるハンドラ。 次の項目は、パラメータについて説明します。func main()
: Function Compute関数のコードを実行するためのエントリポイント。 Goプログラムにはmain
関数が含まれている必要があります。fc.Start(HandleRequest)
コードを使用すると、プログラムをAlibaba Cloud Function Computeで実行できます。
イベントハンドラ署名
次の項目には、有効なイベントハンドラ署名が一覧表示されます。 その中で、InputType
とOutputType
はencoding/json
標準ライブラリと互換性があります。
Function Computeは、json.Unmarshal
メソッドを使用して入力InputType
を逆シリアル化し、json.Marshal
メソッドを使用して返されたOutputType
をシリアル化します。 関数によって返されるデータを逆シリアル化する方法の詳細については、「JSON Unmarshal」をご参照ください。
func ()
func () エラー
func (InputType) エラー
func () (OutputType, error)
func (InputType) (OutputType, error)
func (context.Context) エラー
func (context.Context, InputType) エラー
func (context.Context) (OutputType, error)
func (context.Context, InputType) (OutputType, error)
次のルールに基づいてハンドラーを使用する必要があります。
ハンドラーは関数である必要があります。
ハンドラーには、最大2つの入力パラメーターを含めることができます。 ハンドラーに2つの入力パラメーターが含まれている場合、最初の入力パラメーターは
context.Context
である必要があります。ハンドラーは最大2つの値を返すことができます。 値が1つだけ返される場合、値は
error
タイプを示す必要があります。 2つの値が返された場合、2番目の値はエラー
メッセージを示す必要があります。
次のセクションでは、ハンドラーのサンプルコードについて説明します。
event-struct.go:
event
オブジェクトがSTRUCT型であるハンドラーのサンプルコード。event-string.go:
event
オブジェクトがSTRING型であるハンドラーのサンプルコード。event-map.go:
event
オブジェクトがmap[string]interface{}
型であるハンドラーのサンプルコード。
他のハンドラーのサンプルコードの詳細については、「examples」をご参照ください。
背景
コンテキストの使用方法の詳細については、「コンテキスト」をご参照ください。
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トリガーまたはカスタムドメイン名を使用して呼び出すことができます。 API操作を使用しているが、設定されたテストパラメーターがHTTPトリガーの要求形式要件に準拠していない場合、エラーが報告されます。
たとえば、リクエストパラメーターを "Hello, FC!"
として設定した後、function Computeコンソールで [Test Function] をクリックして関数を呼び出すと、次のエラーメッセージが返されます。
{
"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}"
}
元のリクエストイベントのペイロードを取得する場合は、次の例に示すようにハンドラーを使用できます。
// 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)
}