Azure Container Apps で動かす Goアプリから Dapr 経由でHTTPとかSMTPのサービスを使ってみます。合わせて、よく使いそうなSendGridでメール送信、Cronで定期実行も試したので記載。
まずは単純にnet/httpパッケージで、サンプルコードを実行するHTTPサーバーを実装。
type service struct { client dapr.Client } func main() { // Dapr cli, err := dapr.NewClient() if err != nil { panic(err) } defer cli.Close() svc := &service{ client: cli, } http.HandleFunc("/cron", cron) http.HandleFunc("/smtp", svc.Smtp) http.HandleFunc("/sendgrid", svc.SendGrid) http.HandleFunc("/http", svc.Http) http.ListenAndServe(":8080", nil) }
仕様を参考にContainer AppsでDaprを呼ぶコードを実装。コンポーネントの設定からContainer Appsで不要な schema を削除していきます。
Example
HTTP, SMTP, SendGridのOutput Bindingは、リクエスト内容は異なりますが、dapr.NewClient() で作ったclientでリクエストを送るだけですので基本的には同じです。
HTTP
- name: http type: bindings.http version: v1 metadata: - name: url value: http://example.com
func (svc *service) Http(w http.ResponseWriter, r *http.Request) { ctx := r.Context() in := &dapr.InvokeBindingRequest{ Name: "http", Operation: "get", Data: []byte("\"Hello, HTTP.\""), Metadata: map[string]string{"path": "/"}, } out, err := svc.client.InvokeBinding(ctx, in) if err != nil { fmt.Fprint(w, err.Error()) return } data := string(out.Data) log.Print("Hello, HTTP.") fmt.Fprint(w, data) }
SMTP
- name: smtp type: bindings.smtp version: v1 metadata: - name: host value: "example.com" - name: port value: "587" - name: user value: "USER" - name: password value: "PASSWORD" - name: skipTLSVerify value: true - name: emailFrom value: "test@example.com" - name: emailTo value: "test@example.com" - name: subject value: "Example Smtp"
func (svc *service) Smtp(w http.ResponseWriter, r *http.Request) { ctx := r.Context() in := &dapr.InvokeBindingRequest{ Name: "smtp", Operation: "create", Data: []byte("\"Hello, SMTP.\""), Metadata: map[string]string{"subject": "SMTP"}, } _, err := svc.client.InvokeBinding(ctx, in) if err != nil { fmt.Fprint(w, err.Error()) return } log.Print("Hello, SMTP.") fmt.Fprint(w, "OK. SMTP.") }
Twilio SendGrid
- name: sendgrid type: bindings.twilio.sendgrid version: v1 metadata: - name: emailFrom value: "test@example.com" - name: emailTo value: "test@example.com" - name: subject value: "Example SendGrid" - name: apiKey value: "APIKEY"
func (svc *service) SendGrid(w http.ResponseWriter, r *http.Request) { ctx := r.Context() in := &dapr.InvokeBindingRequest{ Name: "sendgrid", Operation: "create", Data: []byte("\"Hello, SendGrid.\""), Metadata: map[string]string{"subject": "SendGrid"}, } _, err := svc.client.InvokeBinding(ctx, in) if err != nil { fmt.Fprint(w, err.Error()) return } log.Print("Hello, SendGrid.") fmt.Fprint(w, "OK. SendGrid.") }
Cron
cronはコンポーネントの名前に設定したエンドポイントに、metadataに設定されたタイミングで HTTP POST リクエストが来ます。サンプルはログに「Hello, Cron.」と出力していますので、Log Analyticsの設定をしてログで確認。
- name: cron type: bindings.cron version: v1 metadata: - name: schedule value: "@every 10m"
func cron(w http.ResponseWriter, _ *http.Request) { log.Print("Hello, Cron.") fmt.Fprint(w, "OK. Cron.") }
デプロイ
ACRなどを利用してAZコマンドで試すときは、 components.yaml などに上記のコンポーネント設定をまとめて1ファイルで記載し、az containerapp create の dapr-components で、そのファイルを指定。
コマンド例
az containerapp create ` --name $NAME ` --resource-group $RESOURCE_GROUP ` --environment $CONTAINERAPPS_ENVIRONMENT ` --image $IMAGE ` --target-port 8080 ` --ingress 'external' ` --min-replicas 1 ` --max-replicas 1 ` --enable-dapr ` --dapr-app-port 8080 ` --dapr-app-id $ID ` --dapr-components "./components.yaml" ` --registry-login-server $LOG_SERVER ` --registry-username $USERNAME ` --registry-password $PASSWORD
無事デプロイ完了。ポータルでも確認できました。