Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Go / Node.js で入門する gRPC

enta0701
December 21, 2018
170

Go / Node.js で入門する gRPC

enta0701

December 21, 2018
Tweet

Transcript

  1. gRPC Google が2015 年2 月に公開した OSS の RPC フレームワーク Features

    IDL による言語に依存しないインターフェースの定義 API 設計におけるサーバ/ クライアントや他言語の考慮不要 ドキュメント管理不要 HTTP/2 による通信
  2. 0. 準備 protoc コマンドや、必要なパッケージをインストール $ brew upgrade protobuf $ go

    get -u google.golang.org/grpc $ go get -u github.com/golang/protobuf/protoc-gen-go ささっと試したい方はこちら github.com/endotakuya/grpc-example $ go run server.go # Run server $ node /front/app.js # Run Client
  3. 1. .proto ファイル の生成 サーバ/ クライアントで呼び出すメソッドを定義(一部省略) service ArticleService { rpc

    First (Empty) returns (Article) {} rpc Post (Article) returns (Empty) {} } message Article { int32 id = 1; string title = 2; string content = 3; enum Status { DRAFT = 0; PUBLISH = 1; } Status status = 4; }
  4. 3. サーバ側の実装 article.proto に定義した、First メソッド、 Post メソッドを実装 article.pb.go の ArticleServiceServer

    を確認 # article.pb.go type ArticleServiceServer interface { First(context.Context, *Empty) (*Article, error) Post(context.Context, *Article) (*Empty, error) }
  5. 3. サーバ側の実装 First メソッド( server.go#L28 ) type server struct{} func

    (s *server) First(ctx context.Context, in *pb.Empty) (*pb.Article, error) db, _ := initDb() defer db.Close() article := pb.Article{} dist := []interface{}{&article.Id, &article.Title, &article.Content, &article.Stat err := db.QueryRow("SELECT * FROM articles ORDER BY id DESC LIMIT 1").Scan(dist... return &article, err }
  6. 3. サーバ側の実装 Post メソッド( server.go#L38 ) func (s *server) Post(ctx

    context.Context, in *pb.Article) (*pb.Empty, error) { db, _ := initDb() defer db.Close() stmtIns, err := db.Prepare(fmt.Sprintf("INSERT INTO %s (title, content, status) VA defer stmtIns.Close() _, err = stmtIns.Exec(in.Title, in.Content, in.Status) return &pb.Empty{}, err }
  7. 4. クライアント側の実装 First メソッドを叩いて、記事を1件取得 const PROTO_PATH = __dirname + '/../article/article.proto';

    const SERVER_HOST = process.env.SERVER_HOST || 'localhost'; const client = caller(`${SERVER_HOST}:50051`, PROTO_PATH, 'ArticleService'); ... app.get('/', (req, res) => { client.first({}, (err, response) => { res.send(response); }); }); Nodejs だと直接 article.proto を読み込めばOK
  8. 5. 動作確認 +----+-----------------+--------------------------------+--------+ | id | title | content |

    status | +----+-----------------+--------------------------------+--------+ | 3 | メリークリスマス | テーマ忘れてた | 1 | +----+-----------------+--------------------------------+--------+ Go のサーバが立ち上がっていることを確認して、 express を起動 $ node app.js Listening on port 3000
  9. クライアント側の実装 Post メソッドを叩いて、記事を登録 app.post('/new', (req, res) => { let data

    = { title: req.body.title, content: req.body.content, status: parseInt(req.body.status, 10) }; client.post(data, (err, response) => { // ... }); });
  10. call 実際にメソッドを呼ぶ $ grpc_cli call localhost:50051 ArticleService.First '' connecting to

    localhost:50051 id: 3 title: " お腹空いた" content: " 肉が食べたい" status: PUBLISH Rpc succeeded with OK status