Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
8
Help us understand the problem. What is going on with this article?
@disc99

gRPCのMock戦略

More than 1 year has passed since last update.

はじめに

API開発において、サーバとクライアントが別れて開発することは多いと思います。
しかし、そのような場合にクライアントが平行、あるいは先行して開発をすることになると、必要となるサーバが存在しないため開発がしにくくなります。
そこで出てくるのがAPIのモックサーバです。

Dev Mock

クライアント開発時、本物のサーバの代わりにモックサーバを利用し開発を行い、サーバの開発が完了した時点で結合を行うようにします。

ここではよくあるREST APIと比較したgRPCのMockについて記載します。

REST APIのモックサーバ

RESTのモックサーバはホスティングサービスから、単体のツールまで沢山あるので、ここではシンプルなjson-serverを例にしたいと思います。

json-serverによるモック

json-serverを利用した開発は簡単で、レスポンスとなるjsonを定義し、json-serverに読み込ませるだけです。

Terminal
> npm install -g json-server
db.json
{
  "posts": [
    { "id": 1, "title": "json-server", "author": "typicode" }
  ],
  "comments": [
    { "id": 1, "body": "some comment", "postId": 1 }
  ],
  "profile": { "name": "typicode" }
}
Terminal
> json-server --watch db.json

また、CRUD処理やソート、ページングなどもjson-serverの仕組みに乗ることで利用が可能です。

クライアント開発では、事前にjsonの定義でサーバ相当の機能を実現、開発し、サーバ開発が完了した時点で本物のサーバを利用するようにします。

gRPCのモックサーバ

gRPCの開発スタイル

Kobito.XIS1od.png

gRPCにおける開発では概ね以下のフローで行います。

  1. クライアント/サーバ間のインターフェイス定義
  2. protocにより、クライアント/サーバの自動生成
  3. サーバ側の実装
  4. クライアントからサーバの利用

ここで重要なのが、2.クライアント/サーバの自動生成です。

言語依存はありますが、ここで生成されるサーバのコードはほぼそのままサーバとして実行が可能なコードが生成されます。
つまり、RESTでいうjson-serverのような仕組みが公式でサポートされています。

また、生成するサーバのコードも任意の言語で自動生成可能なので、クライアントを実装する開発者が扱いやすい言語のモックサーバで開発が可能です。

ということで、gRPCだと多くの場合、外部のMockツールがなくてもクライアントだけの開発が可能になります。

より簡単にgRPCのモックサーバを

gRPCの開発フローに乗ると、サーバ生成は簡単に行えるようになりますが、RESTのときと比べるとサーバ生成がちょっと手間に感じるかもしれません。
そんなときに便利なのが、Protobuf.jsのdynamic codegenです。

Protobuf.jsを使うとprotoファイルを直接読み込み、モック化したい処理の実装することで、1つのjsファイルだけでモックサーバが用意できます。
後は通常のnodeアプリケーションと同様起動するだけです。

server.js
// proto定義の読み込み
const PROTO_PATH = __dirname + '/../../protos/helloworld.proto'
const grpc = require('grpc')
const protoLoader = require('@grpc/proto-loader')
const packageDefinition = protoLoader.loadSync(/* ... */)
const hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld

// モック
function sayHello(call, callback) {
  callback(null, {message: 'Hello ' + call.request.name})
}

// サーバの設定
function main() {
  const server = new grpc.Server()
  // モックの組み込み
  server.addService(hello_proto.Greeter.service, {sayHello: sayHello})
  server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure())
  server.start()
}

main()
Terminal
> node server.js

単純なnodeのスクリプトになっているので、固定値を返すモックだけでなく、動的な処理を埋め込むのにも便利です。

RESTとのgRPCのMock比較

簡単に比較すると以下の特徴があります。

REST gRPC
機能 シンプルなものから高機能なものまで様々
用途に合わせて選択可能
本物のサーバと同様の機能を実現可能
使い慣れた言語でコントロール
拡張性 DSLや拡張機能、各種設定 使い慣れた言語で拡張できる
学習コスト 学習コストが低いものは機能や拡張性が低く、高機能だと学習コストが上がりやすい gRPCサーバの基礎知識があればよい
保守性 APIの定義を保証する仕組みがないため、別ツールと組み合わせるか、テストなどを行う必要がある スキーマ定義の仕組みが公式サポートのため、インターフェイスが保証されている

※ RESTのモックサーバはツールに依存します

まとめ

gRPCは提供されている仕組みそのものが、Mock機能も兼ねているのでその仕組みに乗るのが便利です!

参考

8
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
disc99
asoview
asoview!(アソビュー)は日本全国のレジャー、体験、遊びが集まる日本最大級のレジャー・体験予約サイトです。「週末どこに行こう?旅先で何して遊ぼう?」というちょっとした不便を解決すべく、いろいろな情報を発信しています。

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
8
Help us understand the problem. What is going on with this article?