github.com
gRPCのようなフレームワークで、違いはHTTP 1.1で動くこととJSONをサポートしてること。
インストール
protoc-gen-twirpの他にprotocとprotoc-gen-goも必要。
$ go get github.com/twitchtv/twirp/protoc-gen-twirp
$ brew install protobuf
$ go get github.com/golang/protobuf/protoc-gen-go
protoファイル
まずprotoファイルを書く。
$ mkdir proto
$ vi proto/hello.proto
syntax = "proto3";
package utahta.twirp.example.helloworld;
option go_package = "helloworld";
service HellowWorld {
rpc Hello(HelloReq) returns (HelloResp);
}
message HelloReq {
string subject = 1;
}
message HelloResp {
string test = 1;
}
protocする
protoファイルからgoファイルをつくる。
$ mkdir helloworld
$ protoc --proto_path=./proto --twirp_out=./helloworld --go_out=./helloworld ./proto/hello.proto
$ ls helloworld
hello.pb.go hello.twirp.go
サーバを書く
$ mkdir server
$ vi server/main.go
package main
import (
"context"
"fmt"
"net/http"
"github.com/utahta/twirp-example/helloworld"
)
type Server struct{}
func (s *Server) Hello(ctx context.Context, req *helloworld.HelloReq) (*helloworld.HelloResp, error) {
return &helloworld.HelloResp{
Test: fmt.Sprintf("Subject: %s", req.Subject),
}, nil
}
func main() {
s := &Server{}
handler := helloworld.NewHellowWorldServer(s, nil)
http.ListenAndServe(":8881", handler)
}
クライアントを書く
$ mkdir client
$ vi client/main.go
package main
import (
"context"
"fmt"
"net/http"
"github.com/utahta/twirp-example/helloworld"
)
func main() {
c := helloworld.NewHellowWorldProtobufClient("http://localhost:8881", http.DefaultClient)
resp, err := c.Hello(context.Background(), &helloworld.HelloReq{Subject: "hello twirp"})
if err != nil {
panic(err)
}
fmt.Printf("%#v\n", resp)
}
最終的に次のようなディレクトリ構成になった。
.
├── client
│ └── main.go
├── helloworld
│ ├── hello.pb.go
│ └── hello.twirp.go
├── proto
│ └── hello.proto
└── server
└── main.go
実行する
まずサーバを実行。
$ go run server/main.go
次にクライアントを実行する。
すると結果が返ってくる。
$ go run client/main.go
&helloworld.HelloResp{Test:"Subject: hello twirp"}
curlで実行する
JSONに対応しているのでcurlを使ってさくっとリクエストできる。
$ curl -H 'Content-Type:application/json' -X POST -d '{"subject":"hello curl"}' "http://127.0.0.1:8881/twirp/utahta.twirp.example.helloworld.HellowWorld/Hello"
雑感
シュッと書いたらProtocolBuffersとJSONで会話できるようになってすごい。便利。
学習コストの低さがなによりいい。