blog.syfm

徒然なるままに考えていることなどを書いていくブログ

一年を振り返り… (2018)

去年は 👇

syfm.hatenablog.com

1月

初日の出

高校の友人らと毎年恒例の初日の出を見に行った。 f:id:ktr_0731:20181228163640j:plain

end of 就活

1月のカレンダーの予定を見てみたら毎週就活関連で東京へ行っていた。1月で全て終わったので以降はだいぶ落ち着いた。

OpenAppLab Aizu LT feat. CyberAgent

会津大学の LT イベントで CyberAgent のエンジニアの方々が来ていた。自分は fmt の実装について話した。

speakerdeck.com

また、CyberAgent のエンジニアの一人として c-bata さんが来ていた。ちょうど自作の CLI ツールで c-bata/go-prompt を使っていて、いろいろお話できて楽しかった。ここで話していた内容が go-prompt v0.2.0 で反映されていて嬉しかった。

qiita.com

読んだ本

SAO アリシゼーション編全巻

たとえとどかぬ糸だとしても1 (百合姫コミックス)

たとえとどかぬ糸だとしても1 (百合姫コミックス)

柴田さんが翻訳をしている本で、リーダブルコードに書かれているような、より良いコードの書き方から、自分が暗黙知として身につけているようなことまで、幅広く書かれていた。

ベタープログラマ ―優れたプログラマになるための38の考え方とテクニック

ベタープログラマ ―優れたプログラマになるための38の考え方とテクニック

2月

インターン

3 月の第 4 週までブロックチェーン関連のインターンをしていた。ブロックチェーンコミュニティがどうも苦手で、最近はあまり関心を持たなくなってしまったけど今後どのように発展していくのかは興味がある。

f:id:ktr_0731:20181229010101j:plain
インターン中住んでいたマンション近くのイルミネーション

Go 1.10 Release Party in Tokyo

Go 1.10 リリース記念のパーティがあり、ちょうどインターン期間中で参加できそうだったので参加してきた。
tenntenn さんたちに誘われ、トークもした。20 分のトークは初めてだったのと、他のスピーカーが Go 界隈の有名人しかいなくてかなり緊張した。それでもトークで話した自作 gRPC クライアントが広く使われるようになったので参加して本当に良かったと思う。

speakerdeck.com

読んだ本

ブロックチェーンアプリケーション開発の教科書

ブロックチェーンアプリケーション開発の教科書

3 月

インターン2

3 月の最終週はネクストカレンシーで cointap のサーバサイドの開発をしていた。残念ながらリリースは中止になってしまったけど、設計に関する議論ができてすごく楽しかった。

深崎暮人

東京から会津へ帰る最後の休日で深崎暮人展に行ってきた。友人のぶんのチケットを取り忘れてしまって本当に申し訳なかった…。

f:id:ktr_0731:20181229011317j:plain
ぶれてる

2、3 月はインターン先でフルタイムで働きながら、業務時間が終わった後アルバイト先の仕事もしていたので非常にしんどい月だった。

4 月

f:id:ktr_0731:20181229011635j:plain

情報処理技術者試験

友人二人と毎度おなじみの情報処理技術者試験を受けた。自分はデータベーススペシャリストを受けて、ぎりぎり合格した ✌️

f:id:ktr_0731:20181229011812j:plain
情報処理技術者試験の朝はいつも霧に包まれている

アルバイトをやめた

会津でちょうど一年くらいやっていたアルバイトをやめた。エンジニアは学生が多く、人数も少なかったけど非常に優秀な人ばかりでここでアルバイトできて良かった。これ以降、インターンを除いて働くのをやめ、学生ニートをしている。

読んだ本

5 巻まで。久しぶりに新しい漫画を買ってみたけど良さそうだった。

5 月

f:id:ktr_0731:20181229012959j:plain

イベントに登壇したりはしてたけど、5 月は全体的に何のイベントもなく穏やかに過ごしていた。

会津 春の大 LT 大会

大 LT 大会なるものがあり、メルカリ、クックパッドGunosyCyberAgent など、Web 系の企業 8 社が集結して各企業のエンジニア + 学生がそれぞれ LT をした。 どのトークもすごく面白かったけど、特に deeeet さんと mametter さんのトークが面白かった。

今学ぶべき技術 by deeeet

techlife.cookpad.com

自分も CLI ツールのアップデートに関する話をした。

speakerdeck.com

あと、3 次会でやったジェンガが神回で、めちゃくちゃ盛り上がって楽しかった。

読んだ本

実践ドメイン駆動設計 (Object Oriented SELECTION)

実践ドメイン駆動設計 (Object Oriented SELECTION)

6 月

f:id:ktr_0731:20181229231924j:plain
すっかり見慣れたキャンパスだ

親族旅行

家族と祖父母と会津や芦の牧に旅行へ行った。自分は会津に住んでいるので、現地で合流した。住んでいると忘れてしまうけど、会津は自然豊かだし歴史もあるのですごく魅力的な土地だと思う。過ごしやすくはないけど。

f:id:ktr_0731:20181229014620j:plainf:id:ktr_0731:20181229014540j:plainf:id:ktr_0731:20181229014538j:plainf:id:ktr_0731:20181229014541j:plain

京都旅行

後述するはてなインターン大同窓会というものに参加するために京都に行くことになったので、せっかくだし一人旅をすることにした。
一週間まるまる時間を取り、そのあいだの授業はサボり、ひたすら行きたい観光地を巡った。宿を伏見区あたりで取り、伏見稲荷大社東福寺に歩いていける距離の場所で過ごしていた。伏見稲荷大社は、平日休日問わず人で溢れかえっているけど、深夜になるとほとんど人がいなくなり閑散とするので夜に行くのをおすすめしたい。さすがに山を登るのは難しいけど千本鳥居までなら明かりがあるし、ものすごく雰囲気があるので本当に良い。
寺院と違い、神社は夜中でも開いているところが多いと思う。

f:id:ktr_0731:20181229224344j:plainf:id:ktr_0731:20181229230615j:plain
藤森神社と貴船神社

f:id:ktr_0731:20181229230616j:plain
なでしこ

f:id:ktr_0731:20181229224412j:plainf:id:ktr_0731:20181229230255j:plain
あがた祭りと大吉山展望台

はてなインターン大同窓会

京都旅行の最終日にははてなインターン大同窓会があった。はてなインターンが 10 周年らしく、歴代のインターン生が一挙に集まるというイベントだった。
全員ではないものの、同期にも久しぶりに会えたし、インターネッツで見たことがある人がたくさんいて楽しかった。一次会自体は昼頃から始まり、酒を飲みつつ流れに沿って移動していたらいつのまにか鴨川にいて、結局終電までやっていた。途中、久しぶりにカマルに行った。カマル最高です。

読んだ本

亜人(12) (アフタヌーンKC)

亜人(12) (アフタヌーンKC)

7 月

親族旅行

親戚と家族、祖父母と房総半島に旅行に行っていた。思い返してみると、なんだか今年は旅行が多かった気がする。

その他にはあんまりイベントはなく、ワールドカップを見てた記憶くらいしかない。

読んだ本

Goならわかるシステムプログラミング

Goならわかるシステムプログラミング

8 月

会津旅行

高校の友人らが会津へ旅行来ていたので、いつもの観光地っぽいところを回った。

インターン

長期休暇の間、インターンをしていた。一つのチームに配属され、チーム内のメンバーとペアプロしながらマイクロサービスを開発していた。久しぶりにペアプロをしたけど、やっぱりやっていて楽しいし、理解度も格段に上がるので好き。一ヶ月半くらいしかいなかったけど、それなりに成果は出せたと思うので良かった。

GopherCon 2018

メルカリのスカラシップ制度を利用して GopherCon 2018 に行ってきた。(実質) 初海外で、何もかも新鮮だった。

f:id:ktr_0731:20181229234424j:plainf:id:ktr_0731:20181229233804j:plain
会場の様子

f:id:ktr_0731:20181229234218p:plain
自分と osamingo さん

GopherCon 2018 の詳しい様子は 👇

tech.mercari.com

読んだ本

Clean Architecture 達人に学ぶソフトウェアの構造と設計

Clean Architecture 達人に学ぶソフトウェアの構造と設計

9 月

伊香保温泉旅行 & ISUCON 8

ISUCON 8 をやっていくために伊香保へ旅行へ行き、旅館で戦った。旅館も温泉も温泉街の雰囲気も最高で良かった。
残念ながら ISUCON は負けた…。来年も旅館でやって、今度こそリベンジしたい 💪

f:id:ktr_0731:20181229235253j:plainf:id:ktr_0731:20181229235254j:plainf:id:ktr_0731:20181229235256j:plain

Student Go #1

学生 Go コミュニティによる LT イベント、Student Go に参加していた。以下のようなタイトルで発表もした。

speakerdeck.com

読んだ本

OSSライセンスの教科書

OSSライセンスの教科書

青い春を数えて

青い春を数えて

タイトルの通り、色彩と光について扱った本で、今までイラストを描くときはなんとなくで着色していたので非常に学びがあった。

カラー&ライト ~リアリズムのための色彩と光の描き方~

カラー&ライト ~リアリズムのための色彩と光の描き方~

10 月

技術書典 5

技術書典向けに大学の友人らと一章ずつ執筆し、同人誌にした。スケジュール的にかなり厳しかったけどなんとかなったので良かった。
頒布数もどの程度にすればよくわからなかったけど、完売できたので買ってくれた方々に感謝です。

イラストを描いた

実に一年ぶりくらいにイラストを描いた。ラフ自体は夏のインターン前にできてたけど、あまり進められていなかったので公開までかなり時間がかかった。

f:id:ktr_0731:20181230001247p:plain
夜行

あとは Mercari Tech Conf に行ったり、だいぶサボってた研究を再開したりしていた。

読んだ本

Martin Fowler がいる ThoughtWorks のエンジニアが書いたアーキテクチャに関する本。タイトルに惹かれてなんとなく買った本だけど、多くの学びがあって面白かった。継続的な進化を続けるために、評価基準を定義し、それを評価するための適用度関数を用意するという試みはとても興味深かった。その他にも、モノリスからマイクロサービスまでの範囲でアプリケーション・モジュールの粒度が様々なアーキテクチャたちが紹介されていて、これも個人的には新鮮だった。当たり前だけど、世の中にはモノリスとマイクロサービス以外の選択も十分存在するということを思い出させてくれた。

進化的アーキテクチャ ―絶え間ない変化を支える

進化的アーキテクチャ ―絶え間ない変化を支える

Coders at Work プログラミングの技をめぐる探求

Coders at Work プログラミングの技をめぐる探求

11 月

f:id:ktr_0731:20181230001449j:plain

11 月からはひたすら WHITE ALBUM2 をやっていた記憶しかない…。なんとなくで買ったものの、シナリオが傑作で何度も心に深い傷を負ったので、感傷的になりたい人におすすめ。11 月頃から始めて定量的に進めていたにもかかわらずすべてのシナリオが終わったのはクリスマスイブ直前だった。

読んだ本

以前から欲しいと思っていた柴田さんの書いた本。大学の売店で偶然見かけたので買った。柴田さんのプログラマ人生で得た経験がここに集約されていて、自分もずっとコードを書いていたいと改めて感じさせてくれた良い本だった。

プログラマー”まだまだ”現役続行 (技評SE選書)

プログラマー”まだまだ”現役続行 (技評SE選書)

12 月

聖地巡礼

f:id:ktr_0731:20181230002504j:plain

Go Conference 2018 Autumn

久しぶりに GoCon へ参加してきた。次はネタがあれば発表したい…! f:id:ktr_0731:20181230002713j:plain

クリスマスパーティ

大学の友人らとクリスマスパーティをした。全員が集まれるのは今年が最後なので寂しくなる。

f:id:ktr_0731:20181230002903j:plainf:id:ktr_0731:20181230002905j:plain

中学校の同窓会

成人式以来の久しぶりの同窓会だった。懐かしい顔ぶれですごく楽しかったし、いろんなことを思い出した。また集まれる機会があればいいなぁと思う。

読んだ本

並行計算のモデルの一つである CSP の紹介や、実践的な Go での並行処理パターン、Go のランタイムの仕組みなど幅広い内容で、非常に中身が濃い本だった。
これを読んでからより素直な並行処理を Go で書けるようになったので、並行処理に慣れていない Gopher はぜひ読んでおくと良いと思った。

Go言語による並行処理

Go言語による並行処理

今年買ったけど読めなかった本・読んでいる途中の本

今年もたくさんの未読本がスタックされた。第 4 Q は全然本が読めていなかったので反省したい。来年はもっと計画的に読んでいくぞ!

必要な箇所をかいつまんで読んでいたけど、読み切ったと言うには程遠い。

プロフェッショナルSSL/TLS

プロフェッショナルSSL/TLS

こちらに関しては全然読めていない…。

プロフェッショナルIPv6

プロフェッショナルIPv6

7 割くらい読み終わったけど、最近読めていないので全然終わらない。あと、内容がかなり難解なので繰り返し読まないといけないと思う。

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

オブジェクト指向入門 第2版 原則・コンセプト (IT Architect’Archive クラシックモダン・コンピューティング)

今読んでいる本で、半分くらいまで読み終わった。ソフトウェアの複雑さをいかにして減らすか、という目標を達成するためにコードに対してどうアプローチしていくかを書いた本。設計パターンやデザインパターンの本は多いけど、こういった本は意外と少ない。自分が読んだ本の中でそれっぽいのは「オブジェクト指向のこころ」くらい?こちらも良い本なのでおすすめ。

A Philosophy of Software Design

A Philosophy of Software Design

オブジェクト指向のこころ (SOFTWARE PATTERNS SERIES)

オブジェクト指向のこころ (SOFTWARE PATTERNS SERIES)

終わりに

去年がすごく充実していたので、今年はそれが落ち着いて静かな年になるかな〜と思っていたら、GopherCon で発表してたり、何度も旅行行ってたりしてて、去年に負けず劣らずかなり充実していた。
今年は、なにを判断するのにも必ず複数の基準を設けて総合的に判断できるようになってきた年だった。なので良くわからない Twitter の過激な意見とかに引っ張られたりするようなこともなくなったのでだいぶ精神的に成長した気がする。

自分は大学院へは行かずに就職をするので、来年の春からはついに社会人になる。環境も大きく変わって大変だろうけど楽しみなのでこれから頑張っていきたい。

dept を使った Go ツールの依存管理

はじめに

Go プロジェクトでは、しばしば静的解析ツールが使用されます。例えば、自分のあるプロジェクトで考えてみると、ソースコードの整形には gofmt 、lint には golangci-lint/golangci-lint 、モック用コードの生成には matryer/moq 、CI でのリリース作業では mitchellh/goxtcnksm/ghr が使われています。Go は静的解析を行いやすいプログラミング言語であるため、こうした静的解析ツールは日常的に使用されています。

しかし、Go プロジェクトにおいて、そういったツールの管理に関する問題がいくつか挙げられます。

  1. ツールのバージョン管理が煩雑
  2. ツールの統一的なインストール方法がない

ツールのバージョン管理が煩雑

Go 1.11 以前のバージョンでは、go getgo1 タグ or ブランチがない限り最新のソースコードを取得します。(go1 については budougumi0617 さんの記事 が詳しいです。)
ただ、ほとんどのリポジトリでは上記のようなタグ or ブランチが用意されていないため、あまり有用ではないと感じています。

同様の理由で go get の対象パッケージの依存パッケージ群のバージョンも管理できません。(ただし、リモートリポジトリに vendor ディレクトリがある場合はそちらに配置されているパッケージが優先的に使われます。)

ツールの統一的なインストール方法がない

Go ツールのインストールは主に go get によって行われます。ツールセットをインストールしようとする場合、例えばあるプロジェクトでは README.md に記述された go get スニペットをコピペして実行したり、またあるプロジェクトでは Makefile に記述したりと様々な方法があり、ツールセットをインストールするための方法にばらつきがあります。

ktr0731/dept

幸いなことに、1 つ目の問題は Go Modules の登場によって解決されましたが、2 つ目の問題は依然として残っていました。
この問題を解決するために、dept というツールをつくりました。このツールは、プロジェクトで使用するツールセットの依存管理を行い、Go Modules を利用して依存解決を行います。 以降ではその詳細について紹介します。

github.com

Go Modules におけるツールの依存管理

Go 1.11 では Russ Cox により提案された Go Modules が実験的に導入されました。 Go Modules では、関連のある複数のパッケージをまとめたものをモジュールとして定義し、それらをセマンティックバージョニングで管理し、セマンティックインポートバージョニングによって依存解決を行います。 ライブラリだけでなくツールもモジュール単位になりうるため、セマンティックバージョニングでモジュールを管理するだけでその恩恵を受けることができます。

詳細を解説すると、このポストの本題から外れてしまうので省略します。Go Modules に関する情報はすべて以下の Wiki にまとめられています。

github.com

ツールの依存管理については Wiki に一例が紹介されています。
この方法では、tools ディレクトリに tools.go という、使用したいツールのパッケージをブランクインポートした Go ファイルを作成し、go install <package> を行うことでそれらの依存を go.mod に記録しつつ、バイナリを生成します。

この方法は、新しいメカニズムを入れずに実現できますが、ワークフローが少々煩雑です。
また、依存管理されるツールのモジュールは go.mod に記述されますが、npm の devDependencies などとは異なり、開発時のみに使用するモジュールを分けて管理することができません。

dept は、Go Modules の持つ強みを活かしつつ、上記の様な問題を解決した、より簡単に扱えるラッパーツールです。

dept を使った依存管理

deptgo コマンドと似た非常にシンプルなインターフェースを提供しています。プロジェクトに新しくツールを追加するには dept get を使います。modules-aware mode の go get と同様にバージョンを指定してインストールすることもできます。

$ dept init
$ dept get github.com/mitchellh/gox github.com/tcnksm/ghr@v0.12.0

dept get を行うと、プロジェクトルートに gotool.mod が生成されます。以降はこのファイルを元にツールセットの決定論的なビルドを行うことができます。 透過的にツールを使用したい場合、dept exec が、その他の理由で生成されたバイナリを直接扱いたい場合は dept build が使えます。

$ dept exec ghr -v
ghr version v0.12.0

$ dept build
$ ls _tools
ghr             gox

この他にもいくつか便利なサブコマンドがあります。気になった方はぜひ dept -h を叩いてみてください。

dept の実装

これ以降は dept がどうやって上記のような機能を実装しているのかや、それに伴うつらみを紹介します。

ラッパーツールと銘打っている通り、dept 内部では go コマンドのサブコマンドである go get や、go buildgo mod などのコマンドを実行しています。
例えば、新しいツールを依存に追加する dept get であれば、go getgo build などを叩いたりします。また、これらのコマンドは Go Modules を使うために常に modules-aware mode で実行されます。
このあたりの操作は多少の違いはあれど、上記で紹介した tools.go を用意する方法とほとんど同様です。

これらのコマンドから使われる Go Modules のマニフェストファイル、go.mod は、以下のような理由からプロジェクトで使用される go.mod とは別に管理しています。

  • プロジェクトで使用するモジュールと、ツールが必要とするモジュールを別々に管理したいため
  • dept のリネーム機能や、一つのモジュール内に複数のツールがある場合に go.modシンタックスではそれらを表現できないため

特に二番目の理由はなかなか厄介な問題です。go.modJSON や TOML 等のデータ記述言語ではなく、独自のシンタックスを持った DSL であるため、拡張が非常に困難です。 以前、以下の issue にて議論が行われていましたが、

  1. go.mod を読み書きできる、十分なドキュメントがある API を提供するのであれば言語がなんであれ問題ない
  2. 既存のシンタックスは必要最小限のものであるため、現段階では DSL をそのまま使うべき

といった理由で現在のシンタックスが継続して使われるようになりました。

github.com

特に read-only な操作であれば、go mod edit -json を使うことで JSON として取得できるため、現状大きな不満はありません。

ただ、今回のような go.mod の表現を拡張するといった特異なケースだとやっぱり API が欲しくなります。
今の go.mod の読み書きを扱うパッケージは以下の様に internal 以下に存在し、dept でもこのパッケージを引っ張ってきて使用しています。

modfile - GoDoc

今後このパッケージは public にすることが予定されているようなので、これを心待ちにしています…。

まとめ

  • dept を使うと、ツールの管理が楽になるよ
  • go.mod DSL は拡張が難しくてしんどい時がある

gRPC-Web Internals

これは Aizu Advent Calendar 2018 の 2 日目の記事です。
1 日目は @Ruto009 さんで、3 日目は @ayanoaizu さんです。

adventar.org

gRPC-Web is GA!

今年の 10 月末に、gRPC-Web がついに GA (Generally Available) となり、メジャーリリースが行われました 🎉

grpc.io

gRPC は、HTTP/2 ベースの RPC フレームワークで、IDL (Interface Definition Language) を元にクライアント・サーバのスタブを各プログラミング言語向けに生成できる、といった特徴を持っています。
gRPC-Web は、gRPC ベースのプロトコルで、gRPC を Web ブラウザ環境から利用するために作られました。

では、Web ブラウザ環境で動作するために、gRPC-Web ではどのような拡張が行われているのでしょうか?
この記事では gRPC と gRPC-Web を比較し、その違いを見ていきたいと思います。

この記事は、今年行われた技術書典 5 で執筆した章「gRPC Web Internals」を元に構成されています。
技術書典からしばらく経ったため、この章のみを一般公開したいと思います。この記事より詳しい解説はそちらの方をぜひご覧ください!

github.com

仕様

gRPC と gRPC-Web の仕様は共に gRPC の GitHub リポジトリ内に存在します。

github.com

gRPC の仕様は以下のディレクトリに、

grpc/PROTOCOL-HTTP2.md at master · grpc/grpc · GitHub

gRPC-Web の仕様は以下のディレクトリにあります。

grpc/PROTOCOL-WEB.md at master · grpc/grpc · GitHub

以下ではこれらの仕様から特に特徴的な箇所を紹介します。

HTTP のプロトコルバージョン

gRPC は、HTTP/2 ベースのプロトコルです。すべての通信は HTTP/2 によって行われ、デフォルトで TLS が有効になっています。ただし、開発時などの都合のために TLS を無効にした非セキュアな通信を行うこともできます。例えば、Go がクライアント・サーバの場合、WithInsecure オプションを使うことで実現可能です。

それに対し、gRPC-Web は状況に応じて HTTP/1 または HTTP/2 のいずれかが使用されます。ほとんど全ての Web ブラウザでは HTTP/2 での通信において TLS が必須となっているため、そういった場合は HTTP/1 による非セキュアな通信にフォールバックされます。

また、HTTP/2 はバイナリベースのプロトコルであるのに対し、HTTP/1 はテキストベースのプロトコルです。gRPC のデフォルトのシリアライザである Protocol Buffers 3 によってシリアライズされたデータを HTTP/1 で扱うためには、その内容をテキストとして扱えなければいけません。そのため、gRPC-Web では Base64 をデフォルトのエンコーダ / デコーダとして規定しています。実際、gRPC-Web による通信をブラウザから見てみると Base64 エンコードされていることが分かります。

f:id:ktr_0731:20181130215714p:plain
Base64 エンコードされたレスポンスボディ

gRPC-Web のデザインゴールの一つとして、「HTTP/1 で代替できない、HTTP/2 特有のフレームや振る舞いを分離する」といったものがあります。
例えば、gRPC の仕様 で使用されている GOAWAY フレームや、PING フレームを HTTP/2 での通信でも使用せずに、HTTP/1 のセマンティクスのみで表現できるようになっています。

RPC 方式

gRPC には、

  • Unary RPC
  • Server streaming RPC
  • Client streaming RPC
  • Bidirectional streaming RPC

の 4 種類の RPC 方式があります。
Unary RPC は一つのリクエストに対して、一つのレスポンスが返り、Server streaming RPC は一つのリクエストに対して、複数のレスポンスが返ります。
Client streaming RPC は Server streaming RPC とは逆に、複数のリクエストに対してただ一つのレスポンスが返ります。
Bidirectional streaming RPC は複数のリクエストに対して複数のレスポンスが返ります。

Unary / Server streaming RPC

これら二つの RPC 方式は gRPC-Web でもサポートされています。レスポンスボディは Base64エンコードされていますが、その中身は通常の gRPC と同様のスキーマになっています。このスキーマABNF で表現されています。
後述する improbable-eng/grpc-web では、トレイラーヘッダ名が lower-case header ではなく MIME header 形式になっているという、gRPC / gRPC-Web の仕様から外れた実装がありましたが、v0.6.4 で修正されています。

Client / Bidirectional streaming RPC

現在、これらの RPC 方式は gRPC-Web の仕様では 定義されていません。ただし、grpc/grpc-web にあるロードマップによると、将来的に WebSocket を使った実装を追加する可能性があるといった記述がありますが、これはディスカッションで提案されているもので、仕様の一部ではありません。

バイナリシリアライザからの切り替え

gRPC では Protocol Buffers や FlatBuffers のようなバイナリベースのシリアライザが使用されていますが、これらはクライアントがスキーマを把握するために巨大なメタデータを必要とします。また、Web ブラウザ上でのデシリアライズも CPU 負荷が大きくなりやすいため、Gmail の特殊な JSON のように軽量で効率的なテキストベースの形式に切り替えていくことを検討しています。

その他の gRPC との違い

他にもいくつかロードマップに挙げられている機能があります。詳しくはリンク先を見てみてください。

gRPC-Web の実装たち

ここまで、gRPC-Web の仕様をかいつまんで見てきました。では次に実際の実装はどのようなものがあるか見てみましょう。
現在、主もアクティブな実装が二つ存在します。一つ目が gRPC オーガニゼーションに属している grpc/grpc-web、もう一方が Improbable 社のエンジニアを中心に開発されている improbable-eng/grpc-web です。

github.com

github.com

これらのクライアント・サーバ実装の互換性を知るには以下のリポジトリが役に立ちます。

github.com

プロキシ

gRPC-Web は gRPC の拡張プロトコルであるため、クライアント・サーバ間でその差異を吸収するためのレイヤーが必要となります。これにはいくつかの方法があります。

grpc/grpc-web

このリポジトリには、JavaScript および TypeScript のクライアントを生成するための Protocol Buffers プラグインおよびプロキシ関連のファイルが含まれています。
プロキシには以下が使用可能です。

improbable-eng/grpc-web

このリポジトリにも grpc/grpc-web と同様に JavaScript / TypeScript クライアント向けのプラグイン、および Go 向けのサーバライブラリなどが含まれています。
プロキシには以下が基本的に使用可能です。

  • Envoy
  • grpcwebproxy

また、improbable-eng/grpc-web では grpcweb という Go パッケージが提供されており、プロキシを使わずに、grpc.Server をラップすることで gRPC ⇔ gRPC-Web の相互変換を行うことができます。

improbable-eng/grpc-web の最も特筆すべき点として、Client / Bidirectional streaming RPC を独自に実装していることが挙げられます。
この実装には、WebSocket が使われています。
そのため、improbable-eng/grpc-web を使うことで、これらの RPC も扱うことができるようになり、ネイティブの gRPC と同等の機能性を得ることができるようになります。
ただし、Envoy や NGINX などのプロキシを使うことができなくなる点に注意してください。
また、前述の通り、WebSocket を使用した実装は仕様にはない拡張であるため、今後 grpc/grpc-web で実装されるとも限りません。

gRPC-Web の gRPC サポート

将来的に、WHATWG Fetch / Streams が多くのモダン Web ブラウザで使用可能になった段階で gRPC-Web はネイティブの gRPC プロトコルをサポートすることが検討されています。
ただし、以下の各 Web ブラウザのサポート状況を見る限り、当分先になりそうな気がします。

developer.mozilla.org

developer.mozilla.org

gRPC-Web がネイティブ gRPC プロトコルとの通信をできるようになれば、当然 Client / Bidirectional streaming も可能になります。
gRPC-Web / gRPC の違いを意識せずに透過的に利用できるようになるにはここまで成熟する必要があるでしょう。

宣伝

対話的にサーバと通信ができる gRPC クライアントの Evans を作っています。

github.com

Evans は gRPC-Web をサポートしているので、通常の gRPC サーバと同様にテストすることができます! 多分汎用 gRPC クライアントで gRPC-Web をサポートしているのは Evans だけだと思います。

ぜひ使ってみてください 🙏