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

Go / Node.js で入門する gRPC

B002134f2e824b2100761da10a9765a9?s=47 enta0701
December 21, 2018
100

Go / Node.js で入門する gRPC

B002134f2e824b2100761da10a9765a9?s=128

enta0701

December 21, 2018
Tweet

Transcript

  1. Go / Node.js で入門する gRPC Created by @endotakuya

  2. gRPC 使ってますか?

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

    IDL による言語に依存しないインターフェースの定義 API 設計におけるサーバ/ クライアントや他言語の考慮不要 ドキュメント管理不要 HTTP/2 による通信
  4. None
  5. そもそも RPC とは 遠隔手続き呼出し(リモートプロシージャコール) Features ローカルなサブルーチン呼び出しと基本的に同じコードでリモート呼び 出しを行える プログラムから別のアドレス空間(通常、共有ネットワーク上の別 のコンピュータ上)にあるサブルーチンや手続きを実行することを 可能にする技術

    “ “
  6. How to use

  7. 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
  8. 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; }
  9. 2. .proto をコンパイル サーバ/ クライアントのひな形になるコードを生成 今回は Go 用に吐き出し $ protoc

    article/article.proto --go_out=plugins=grpc:. article.pb.go が生成される
  10. 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) }
  11. 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 }
  12. 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 }
  13. 4. クライアント側の実装 多言語での動作を確認するため、Nodejs で実装 入れたパッケージはこちら { "dependencies": { "body-parser": "^1.18.3",

    "ejs": "^2.6.1", "express": "^4.16.4", "grpc": "^1.16.1", "grpc-caller": "^0.11.0" } }
  14. 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
  15. 5. 動作確認 +----+-----------------+--------------------------------+--------+ | id | title | content |

    status | +----+-----------------+--------------------------------+--------+ | 3 | メリークリスマス | テーマ忘れてた | 1 | +----+-----------------+--------------------------------+--------+ Go のサーバが立ち上がっていることを確認して、 express を起動 $ node app.js Listening on port 3000
  16. None
  17. クライアント側の実装 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) => { // ... }); });
  18. http://localhost:3000/new にアクセスし、フォームから送信 Insert されれば成功

  19. 便利なコマンド

  20. grpc_cli クライアントを作成してデバックするのが面倒… grpc_cli なら CLI 上から gRPC によるインターフェース等を確認できる インストール方法は次を参考に ローカル環境でgRPC

    をデバッグする方法 ただ、途中こけるので、以下を実行 $ brew install gflags
  21. call 実際にメソッドを呼ぶ $ grpc_cli call localhost:50051 ArticleService.First '' connecting to

    localhost:50051 id: 3 title: " お腹空いた" content: " 肉が食べたい" status: PUBLISH Rpc succeeded with OK status
  22. 詳細は Qiita へ Go / Node.js で入門する gRPC

  23. いい gRPC ライフを