Goaとは
GoaはGoのフレームワークの1つで、REST APIに特化しています。
ビジネスロジックの開発に専念できるよう設計されており、デザインファイルを定義することで、サーバ・クライアント・ドキュメント(swagger)の3つを生成することができるという特徴を持っています。
インストール
Goが使える状態になっていることは前提として、下記でインストールできます。
% go get -u goa.design/goa/v3 % go get -u goa.design/goa/v3/...
ちなみに、この時点で私ははまりまくりました。。。。
興味ある方は下記をどうぞ。
Getting Started
公式サイトに Getting Started というページがあるので、これを試してみました。
https://goa.design/learn/getting-started/
% mkdir -p test/design % cd test % go mod init calc go: creating new go.mod: module calc
必要であればここで Goa を最新版に更新しておきます。
% go get -u goa.design/goa/v3 % go get -u goa.design/goa/v3/...
下記のようなデザインファイルを作成します。
package design
import (
. "goa.design/goa/v3/dsl"
)
var _ = API("calc", func() {
Title("Calculator Service")
Description("Service for adding numbers, a Goa teaser")
Server("calc", func() {
Host("localhost", func() {
URI("http://localhost:8000")
URI("grpc://localhost:8080")
})
})
})
var _ = Service("calc", func() {
Description("The calc service performs operations on numbers.")
Method("add", func() {
Payload(func() {
Field(1, "a", Int, "Left operand")
Field(2, "b", Int, "Right operand")
Required("a", "b")
})
Result(Int)
HTTP(func() {
GET("/add/{a}/{b}")
})
GRPC(func() {
})
})
Files("/openapi.json", "./gen/http/openapi.json")
})
Goaでコードを generate します。
% goa gen calc/design gen/calc/client.go gen/calc/endpoints.go gen/calc/service.go gen/grpc/calc/client/cli.go gen/grpc/calc/client/client.go gen/grpc/calc/client/encode_decode.go gen/grpc/calc/client/types.go gen/grpc/calc/pb/calc.proto gen/grpc/calc/server/encode_decode.go gen/grpc/calc/server/server.go gen/grpc/calc/server/types.go gen/grpc/cli/calc/cli.go gen/http/calc/client/cli.go gen/http/calc/client/client.go gen/http/calc/client/encode_decode.go gen/http/calc/client/paths.go gen/http/calc/client/types.go gen/http/calc/server/encode_decode.go gen/http/calc/server/paths.go gen/http/calc/server/server.go gen/http/calc/server/types.go gen/http/cli/calc/cli.go gen/http/openapi.json gen/http/openapi.yaml
ちなみに、上記で、、、
exit status 1 failed to run protoc: exec: "protoc": executable file not found in $PATH:
このようにエラーが出た場合には、protobuf をインストールする必要があります。
Mac であれば、Homebrew でインストールできます。
% brew install protobuf
次に、下記のようにして example をダウンロードします。
% goa example calc/design calc.go cmd/calc-cli/grpc.go cmd/calc-cli/http.go cmd/calc-cli/main.go cmd/calc/grpc.go cmd/calc/http.go cmd/calc/main.go
これで基本的には準備は整ったのですが、 add API の内容が足算になっていないので、下記のように calc.go を正しい内容に修正します。
func (s *calcsrvc) Add(ctx context.Context, p *calc.AddPayload) (res int, err error) {
return p.A + p.B, nil
}
これですべて用意ができたのでビルドします。
クライアントとサーバの両方をビルドします。
% go build ./cmd/calc && go build ./cmd/calc-cli go: finding module for package github.com/grpc-ecosystem/go-grpc-middleware go: downloading github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 go: found github.com/grpc-ecosystem/go-grpc-middleware in github.com/grpc-ecosystem/go-grpc-middleware v1.2.0
確認
サーバ実行
% ./calc [calcapi] 01:28:20 HTTP "Add" mounted on GET /add/{a}/{b} [calcapi] 01:28:20 HTTP "./gen/http/openapi.json" mounted on GET /openapi.json [calcapi] 01:28:20 serving gRPC method calc.Calc/Add [calcapi] 01:28:20 HTTP server listening on "localhost:8000" [calcapi] 01:28:20 gRPC server listening on "localhost:8080"
ここでクライアントを下記のように実行すると、足算した結果が返ってくることが確認できます。
% ./calc-cli --url="http://localhost:8000" calc add --a 1 --b 2 3
サーバ側のログには下記のように出力されました。
[calcapi] 01:28:50 id=vURfjlw7 req=GET /add/1/2 from=127.0.0.1 [calcapi] 01:28:50 id=vURfjlw7 status=200 bytes=2 time=96.551µs
gRPC
ちなみに、、、、上記の例では gRPC にも対応しており、クライアントで下記のように実行すると試せるはずなのですが、、、
./calc-cli --url="grpc://localhost:8080" calc add --message '{"a": 1, "b": 2}'
なぜか下記のようにエラーが出てうまくいっていません(/_\*)
rpc error: code = Unavailable desc = connection closed
たぶん非常に根本的なことが問題なのだと思うのですが、もしご存知の方がいらっしゃれば教えてください(/_\*)
コメント