Go moduleはマイナーバージョンで互換性を壊してはいけない

Posted on
Go grpc

Go module のマイナーバージョンで互換性を壊すと間接的に利用している人たちにも大きな影響を与え、多大な人に迷惑をかけることになる。 そもそも Go module ではマイナーバージョンで互換性を破壊してはいけないとなっているので、それを無視し勝手なポリシーを運用しているライブラリは避けたいところ。

が、しかし grpc-go[google.golang.org/grpc](http://google.golang.org/grpc) )が自分勝手なポリシーで運用していて大変困っている。

golang.org のサブドメインをモジュール名にするなら Go module のポリシーに従ってくれ)

何が問題になるのか

grpc-go@v1.29.0 に依存している ライブラリA があったとする。

自プロジェクトではこの ライブラリA に依存している。 つまり自プロジェクトからは間接的に grpc-go@v1.29.0 に依存してることになる。

ここで自プロジェクトでも直接 grpc-go に依存するような変更を行いたかったとしよう。 この時 grpc-go はアップデートされていて grpc-go@v1.30.0 がリリースされていた。 そして v1.29.0 と v1.30.0 の間で非互換な変更が入っていた。(例えば公開APIの削除)

この状況でどうなるかといえば、v1.30.0 は使えないので v1.29.0 に固定せざるおえない。

ライブラリAgrpc-go の更新に追従する努力をしてくれればいいが、そうでもない場合もある。 上記のようなケースだと ライブラリA 自身も困りアップデートできないということも考えられる。

grpc-go の最新が v1.30.0 なら良いかもしれないが、もっt先に進んでいき乖離が大きくなるとだんだん困ってくる。

マイナーバージョンで互換性を壊すな

grpc-go は v1.30.0 で experimental な API を削除した。

grpc-go 的には experimental な API だから使うほうが悪い というスタンスらしいが、それは grpc-go の勝手なお願いで、マイナーバージョンで互換性を壊す grpc-go が問題である。

Go には experimental な API を明示する方法がない。Deprecate な API は明示でき、IDEであればエディタで deprecate な API かどうか分かる。 しかし experimental な API にはそういうものはない。

もし grpc-go の人が experimental な API を使っている人が悪いと主張するのであれば、まず Go のエコシステムに experimental な API を明示する仕組みを作るべきである。

言語のエコシステムから外れたことをしていて(experimental な API とマイナーバージョンでのバージョン破壊)利用者が悪いと主張するのは筋が悪すぎる。

Go module でライブラリを公開している人たちはマイナーバージョンで互換性を壊してはいけない

メジャーバージョンで互換性を壊す

メジャーバージョンであれば互換性の破壊は問題ない。

Go module は同一ライブラリでメジャーバージョン違いを同時に利用することができる。

ライブラリのメンテナたちには上手く Go module を活用出来ている google/go-github を見習って欲しいところである。