search
LoginSignup
30

More than 1 year has passed since last update.

posted at

updated at

Protocol Buffers 導入メモ Mac/Win

ProtocolBuffers

  • 通信や永続化での利用を目的としたシリアライズフォーマット
  • Googleによって開発されている
  • オープンソースライセンス
  • 多数言語(Java, Python, Objective-C, and C++...)に対応している

JSONや、MessagePackの様につかえる...!!

参考
Protocol Buffers  |  Google Developers
Protocol Buffers - Wikipedia

環境

  • macOS High Sierra
  • Windows 10

手順

  1. protoc を入手
  2. protoファイルを作成
  3. protoc コマンドで言語ごとに使用するファイルを出力
  4. 言語ごとにシリアライズ、デシリアライズ時に上記ファイルを使用

1. Protoc を入手

Mac

Homebrew経由で入手

# terminal等
$ brew update     # formula を更新
$ brew upgrade    # 更新があるパッケージを再ビルドする
$ brew install protobuf # protobufをインストール
$ brew upgrade protobuf # protobufをアップグレード

$ protoc --version
libprotoc 3.6.0

参考
homebrewでprotobufを最新版(3.0.0)にアップグレードする

Win

ここから、protoc-xxx-win32.zipを入手。
C:\Program Files\にProtocフォルダを作って上記zipを解答。
環境変数のPathに C:\Program Files\Protoc\protoc-3.4.0-win32\binを設定。

# powershell等
> protoc --version
libprotoc 3.6.0

(より良い方法があったら教えてくださいm(__)m)

2. protoファイルを作成

Person.proto
message Person {
  required string name = 1;
  required int32 id = 2;
  optional string email = 3;

  enum PhoneType {
    MOBILE = 0;
    HOME = 1;
    WORK = 2;
  }

  message PhoneNumber {
    required string number = 1;
    optional PhoneType type = 2 [default = HOME];
  }

  repeated PhoneNumber phone = 4;
}

上記は公式のサンプルです。

  • required/optionalを定義できる
  • enumを使うことができる
  • messageフィールドで定義した他のmessageを使うことができる(上記では"PhoneNumber")
  • repeatedで繰り返し(配列)を定義できる。
message {
    TYPE NAME = UNIQUE NUMBER
}

が基本形のようです。
詳しくは、公式をチェックしてください
Language Guide (proto3)  |  Protocol Buffers  |  Google Developers

今回は、以下の簡単なexample.protoを使用します。

example.proto
syntax = "proto3";
package example;

message User {
    int32 id = 1;
    string name = 2;
}

3. protoc コマンドで言語ごとに使用するファイルを出力

go言語の場合は、
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
を先に行ってください。 protocコマンドが裏側でprotoc-gen-goを使用しているみたいです。

protocコマンドを使ってファイルを出力します。
protoc --go_out=. -I. example.proto

  • example.pb.go

が出来上がっていると思います。
--xx_out= => xxが言語名、=の後ろにアウトプットしたいパス
-I => インプットフォルダのパス 
詳しくは、
protoc --help
をご確認下さい。

4. 言語ごとにシリアライズ、デシリアライズ時に上記ファイルを使用

ただ、シリアライズして、デシリアライズするシンプルなサンプルを以下に置いておきます。

フォルダ構成

.
├── main.go
└── protos
    └── example.pb.go
main.go
package main

import (
    "log"

    "./protos"
    "github.com/golang/protobuf/proto"
)

func main() {

    //Serialize
    test := &example.User{
        Id:   33,
        Name: "laughing_cat",
    }
    buff, err := proto.Marshal(test)
    if err != nil {
        log.Print("marshal error")
        return
    }
    log.Print("serialize success: ", buff)

    // Deserialize
    parsedTest := &example.User{}
    err = proto.Unmarshal(buff, parsedTest)

    if err != nil {
        log.Print("deserialize error: ", err)
    }
    log.Print("deserialized id :", parsedTest.Id)
    log.Print("deserialized name: ", parsedTest.Name)
}

上記で、シリアライズ=>デシリアライズ が完了するかと思います。
importの時に、*.pb.goファイルのパスを指定するのをお忘れなく。

間違えや訂正があったら教えて頂けると嬉しいですm(_ _)m。

参考

公式
今さらProtocol Buffersと、手に馴染む道具の話
Protocol BuffersでAPI通信 サーバー編【golang】 

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
30