個人メモ：Protocol Buffers

## protobuf？
- 通信規約
- API間、OS間のデータ交換用の形式
- Google提供

## 他の形式との比較
protobuf > json >>> xml


## いい点
- 小さい、早い、簡単
- 一回の作成で、色んな開発言語間で、通信可能

## 悪い点
- 複雑な表現が出来ない
- バイナリデータで保存されるので、jsonみたいに直接見れない


## protocol buffersのインストール
-  [Protocol Buffersダウンロード](https://github.com/protocolbuffers/protobuf)

- zipを解凍し、protoc-x.x.x-win32 を''C:\Program Files''直下に配備
-  環境変数のPathに ''C:\Program Files\Protoc\protoc-x.x.x-win32\bin'' を設定
-  下記表示されればOK

```
C:\Users\～～>protoc --version
libprotoc 3.6.1
```

## protoc-gen-goのインストール
```
go get -u -v github.com/golang/protobuf/protoc-gen-go
```

## protobufを作ってみる

C:\qiita\protobuf\Student.proto

```
// バージョン指定、指定なかったら、デフォルトproto3になる。後ろの`;` を忘れないように
syntax = "proto3";

// 学生というのリクエストを定義
message StudentRequest {
    // タイプなどを定義、後ろの数字1は、順番
    string name = 1;
    int32 age = 2;
}
```

## protobufコンパイル
```
protoc --go_out=./  Student.proto
```

golang用のprotoufファイルが作成される
(何かがいっぱい作られているけど... 次回使ってみる)
`Student.pb.go`

```golang
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: Student.proto

package Student

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

// 学生というのリクエストを定義
type StudentRequest struct {
	// タイプなどを定義、後ろの数字1は、順番
	Name                 string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
	Age                  int32    `protobuf:"varint,2,opt,name=age,proto3" json:"age,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *StudentRequest) Reset()         { *m = StudentRequest{} }
func (m *StudentRequest) String() string { return proto.CompactTextString(m) }
func (*StudentRequest) ProtoMessage()    {}
func (*StudentRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_2f4c3db915bb432d, []int{0}
}

func (m *StudentRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_StudentRequest.Unmarshal(m, b)
}
func (m *StudentRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_StudentRequest.Marshal(b, m, deterministic)
}
func (m *StudentRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_StudentRequest.Merge(m, src)
}
func (m *StudentRequest) XXX_Size() int {
	return xxx_messageInfo_StudentRequest.Size(m)
}
func (m *StudentRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_StudentRequest.DiscardUnknown(m)
}

var xxx_messageInfo_StudentRequest proto.InternalMessageInfo

func (m *StudentRequest) GetName() string {
	if m != nil {
		return m.Name
	}
	return ""
}

func (m *StudentRequest) GetAge() int32 {
	if m != nil {
		return m.Age
	}
	return 0
}

func init() {
	proto.RegisterType((*StudentRequest)(nil), "StudentRequest")
}

func init() { proto.RegisterFile("Student.proto", fileDescriptor_2f4c3db915bb432d) }

var fileDescriptor_2f4c3db915bb432d = []byte{
	// 89 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x0d, 0x2e, 0x29, 0x4d,
	0x49, 0xcd, 0x2b, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x32, 0xe3, 0xe2, 0x83, 0x0a, 0x04,
	0xa5, 0x16, 0x96, 0xa6, 0x16, 0x97, 0x08, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30,
	0x2a, 0x30, 0x6a, 0x70, 0x06, 0x81, 0xd9, 0x42, 0x02, 0x5c, 0xcc, 0x89, 0xe9, 0xa9, 0x12, 0x4c,
	0x0a, 0x8c, 0x1a, 0xac, 0x41, 0x20, 0x66, 0x12, 0x1b, 0x58, 0xbb, 0x31, 0x20, 0x00, 0x00, 0xff,
	0xff, 0x07, 0x2d, 0x31, 0xe4, 0x4f, 0x00, 0x00, 0x00,
}

```