Goブログ

JSON-RPC: インターフェースに関する物語

Andrew Gerrand
2010年4月27日

ここでは、Goのインターフェースによって、既存のコードをリファクタリングして、より柔軟で拡張可能にするのが簡単になった例を紹介します。もともと、標準ライブラリのRPCパッケージは、gobというカスタムワイヤーフォーマットを使用していました。特定のアプリケーションでは、代替ワイヤーフォーマットとしてJSONを使用したいと考えました。

最初に、既存のワイヤーフォーマットの機能を記述するために、クライアント用とサーバー用の2つのインターフェースを定義しました(以下に図示)。

type ServerCodec interface {
 ReadRequestHeader(*Request) error
 ReadRequestBody(interface{}) error
 WriteResponse(*Response, interface{}) error
 Close() error
}

サーバー側では、既存のgob.Encoderの代わりにServerCodecインターフェースを受け入れるように、2つの内部関数のシグネチャを変更しました。そのうちの1つを以下に示します。

func sendResponse(sending *sync.Mutex, req *Request,
 reply interface{}, enc *gob.Encoder, errmsg string)

が、こうなりました。

func sendResponse(sending *sync.Mutex, req *Request,
  reply interface{}, enc ServerCodec, errmsg string)

次に、元の機能を再現するために、簡単なgobServerCodecラッパーを作成しました。そこから、jsonServerCodecを構築するのは簡単です。

クライアント側にも同様の変更を加えた後、これがRPCパッケージで行う必要があった作業の全範囲でした。この作業全体に約20分かかりました!新しいコードを整理してテストした後、最終的な変更セットが提出されました。

JavaやC++のような継承指向の言語では、明らかな道筋は、RPCクラスを一般化し、JsonRPCとGobRPCのサブクラスを作成することでしょう。ただし、その階層に対してさらに直交する一般化を行いたい場合は、このアプローチはトリッキーになります。(たとえば、代替RPC標準を実装する場合など)。Goパッケージでは、概念的に単純であり、記述または変更する必要のあるコードが少ないルートを採用しました。

あらゆるコードベースにとって重要な品質は、保守性です。ニーズが変化するにつれて、コードを簡単かつクリーンに適応させることが不可欠です。そうしないと、コードが扱いにくくなってしまいます。Goの軽量で構成指向の型システムは、スケーリング可能なコードを構造化する手段を提供すると考えています。

次の記事: 新しい講演とチュートリアル
前の記事: サードパーティライブラリ: goprotobufとその先へ
ブログインデックス