Azure Functions で Goはサポートされていない。( Azure Functions でサポートされている言語 )
・・が、カスタム ハンドラーを使用する事によって、サポート外の言語でも Azure Functions として利用する事ができる。
ここでは、カスタムハンドラーを使用して Go で実装した Azure Functions を動作させる方法について記載する。
カスタムハンドラーは軽量のWebサーバとして動作するもので、Functions Host と Web通信する事により動作する。
※ https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-custom-handlers#overview
トリガー |
Functions Host |
カスタムハンドラー |
つまり、Webサーバがかける言語であれば何でも動く。
以下の通り構成する。
+ host.json
+ 関数名
┗ function.json
+ Webサーバ(スクリプト,実行可能ファイルなど)
参考
https://github.com/Azure-Samples/functions-custom-handlers/blob/master/go/host.json
Azure Functions 2.x 以降の host.json のリファレンス
defaultExecutablePath で今回 Go で作成するWebサーバの実行可能ファイルのPATHを指定する。
{ "version": "2.0", "extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle", "version": "[1.*, 2.0.0)" }, "httpWorker": { "description": { "defaultExecutablePath": "MyGoCustomHandlers.exe" } } }
スクリプトのPATH を defaultWorkerPath で指定する。
注) nodejs は Azure functions のサポート対象言語なので、そもそもカスタムハンドラを使用する必要はない。
{ "version": "2.0", "httpWorker": { "description": { "defaultExecutablePath": "node", "defaultWorkerPath": "server.js" } } }
参考: http://json.schemastore.org/function
https://github.com/Azure-Samples/functions-custom-handlers/tree/master/go/BlobTrigger
以下、Blob トリガーにより起動される Functions の例
{ "bindings" : [ { "type" : "blobTrigger", "direction" : "in", "name" : "triggerBlob", "path" : "test-triggerinput-httpworker/{name}", "dataType" : "binary", "connection" : "AzureWebJobsStorage" }, { "type" : "blob", "direction" : "out", "name" : "$return", "path" : "test-output-httpworker/{name}", "dataType" : "binary", "connection" : "AzureWebJobsStorage" } ] }
{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "YOUR_STORAGE_CONNECTION_STRING" } }
ローカルのストレージエミュレータに接続する場合は以下の通り設定する。
: "AzureWebJobsStorage": "UseDevelopmentStorage=true" :
package main import ( "encoding/json" "fmt" "log" "net/http" "os" ) type ReturnValue struct { Data string } type InvokeResponse struct { Outputs map[string]interface{} Logs []string ReturnValue interface{} } type InvokeRequest struct { Data map[string]interface{} Metadata map[string]interface{} } func blobTriggerHandler(w http.ResponseWriter, r *http.Request) { var invokeReq InvokeRequest d := json.NewDecoder(r.Body) decodeErr := d.Decode(&invokeReq) if decodeErr != nil { http.Error(w, decodeErr.Error(), http.StatusBadRequest) return } fmt.Println("The JSON data is:invokeReq metadata......") fmt.Println(invokeReq.Metadata) returnValue := invokeReq.Data["triggerBlob"] invokeResponse := InvokeResponse{Logs: []string{"test log1", "test log2"}, ReturnValue: returnValue} js, err := json.Marshal(invokeResponse) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.Write(js) } func main() { httpInvokerPort, exists := os.LookupEnv("FUNCTIONS_HTTPWORKER_PORT") if exists { fmt.Println("FUNCTIONS_HTTPWORKER_PORT: " + httpInvokerPort) } mux := http.NewServeMux() mux.HandleFunc("/BlobTrigger", blobTriggerHandler) log.Println("Go server Listening...on httpInvokerPort:", httpInvokerPort) log.Fatal(http.ListenAndServe(":"+httpInvokerPort, mux)) }
レスポンスとして以下を返却する。
ペイロードのキー | データ型 | 解説 |
Outputs | JSON | function.json ファイルの bindings 配列によって定義される応答値。 |
Logs | array | Functions の呼び出しログとして表示するメッセージ。 |
ReturnValue | string | レスポンス本文。(function.json ファイルの $return として出力が構成されている場合) |
※ https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-custom-handlers#response-payload
func start
以下のエラーが発生する。
: The 'BlobTrigger' function is in error: The binding type(s) 'blobTrigger, blob' are not registered. Please ensure the type is correct and the binding extension is installed. :
Azure Functions は バージョン2 から バインド拡張機能(Storage Extensions) を別途インストールする必要がある模様。
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-run-local?tabs=macos%2Ccsharp%2Cbash#register-individual-extensions
func extensions install
※ .NET Core 2.x SDK がインストールされている必要があるので、未インストールの場合は https://dotnet.microsoft.com/download からインストールしておく。