web-dev-qa-db-ja.com

JSONとプロトコルバッファーの間に標準のマッピングはありますか?

発表ブログ投稿 のコメントから:

JSONについて:JSONはプロトコルバッファーと同様に構造化されていますが、プロトコルバッファーのバイナリ形式はさらに小さく、エンコードが高速です。ただし、JSONはプロトコルバッファの優れたテキストエンコーディングになります。protobufリフレクションを使用して、JSONとの間で任意のプロトコルメッセージを変換するエンコーダ/デコーダを作成するのは簡単です。これは、AJAXアプリと通信するための良い方法です。ユーザーがページにアクセスしたときに完全なprotobufデコーダーをダウンロードさせるのは多すぎるためです。

aマッピングを準備するのは簡単ですが、2つの分離した開発チームが自然に解決する、2つの間に「明白な」マッピングがあります? 2つの製品がPBデータをサポートし、同じ.proto仕様を共有しているため相互運用できる場合、同じ仕様のJSONリフレクションを個別に導入した場合でも相互運用できるかどうか疑問に思います。たとえば、いくつかの任意の決定が行われる可能性があります。列挙値は、文字列(通常のJSONで人間が読めるようにする)または整数値で表す必要がありますか?

確立されたマッピング、および.proto仕様からJSONエンコーダー/デコーダーを生成するためのオープンソース実装はありますか?

27

はい、プロトコルバッファバージョン3.0.0(2016年7月28日リリース)以降、「バイナリプロトエンコーディングの代わりに、JSONで明確に定義されたエンコーディング」リリースノートで述べたように

https://github.com/google/protobuf/releases/tag/v3.0.

3
Erik Sjölund
7

私が見てきたことから、 Protostuff は、プロトコル定義に基づいて、JSONとしてシリアル化するなど、JavaでのPB作業に使用するプロジェクトです。私は自分で使ったことはなく、良いことを聞いただけです。

6
StaxMan

GeneratedMessageLiteからJSONオブジェクトにマーシャリングする必要がありましたが、アンマーシャリングする必要はありませんでした。 LITE_RUNTIMEオプションでは機能しないため、パンゲアの回答でprotobufライブラリを使用できませんでした。また、既存のプロトコルバッファ用にコンパイルされたコードを生成することで、すでに大規模なレガシーシステムに負担をかけたくありませんでした。 JSONへのマシャリングのために、マーシャリングのためのこの簡単なソリューションを使用しました

    final Person gpb = Person.newBuilder().setName("Bill Monroe").build();
    final Gson gson = new Gson();
    final String jsonString = gson.toJson(gpb);
2
Kirby

さらに考えてみましょう:protobufオブジェクトにゲッター/セッター、または適切に名前が付けられたフィールドがある場合、単純に Jackson JSONプロセッサのデータバインディングを使用できます。デフォルトでは、パブリックゲッター、セッター、パブリックフィールドを処理しますが、これらは単なるデフォルトの可視性レベルであり、変更できます。その場合、Jacksonはprotobufで生成されたPOJOを問題なくシリアライズ/デシリアライズできます。

私は実際に、Thriftで生成されたオブジェクトでこのアプローチを使用しました。そこで設定する必要があったのは、フィールドが明示的に割り当てられているかどうかを確認するためにThriftが追加したさまざまな「isXXX()」メソッドのシリアル化を無効にすることだけでした。

1
StaxMan

まず第一に、データセットをプロトバフに変換することに力を注ぐことを非常に慎重に推論する必要があると思います。ここで、データセットをプロトバフに変換する理由

  1. 型の安全性:検討中のデータの形式に関する保証。
  2. データの非圧縮メモリフットプリント。非圧縮について言及する理由は、ポスト圧縮ではJSON圧縮とプロト圧縮のサイズに大きな違いはありませんが、圧縮にはコストが伴うためです。また、シリアライゼーション/デシリアライゼーションの速度はほぼ同じで、実際のジャクソンjsonはプロトバフよりも高速です。詳細については、次のリンクを確認してください http://technicalrex.com/2014/06/23/performance-playground-jackson-vs-protocol-buffers/
  3. プロトバフはネットワークを介して大量に転送する必要があります。

ProtoBuff定義が定義されている方法でデータセットをJackson JSON形式に変換すると、Protostuff:JsonIoUtil:mergeFrom関数を使用して、ProtoBuff形式に非常に簡単に直接マップできると言います。関数の署名:

public static <T> void mergeFrom(JsonParser parser, T message, Schema<T> schema,  boolean numeric) 

protostuff への参照

0
Pramit