Slide 1

Slide 1 text

Dive into Go Protocol Buffers API v2 With the new reflection features Ryoya Sekino @Go Conference 2021 Spring

Slide 2

Slide 2 text

2 セッションの背景とゴール 背景 ゴール ● Go Protocol Buffers API v2が2020年にリリース ● v1のリリースから10年ぶりのメジャーアップデート ● 充実したreflection機能が公式に提供されるようになった ● Go Protocol Buffers API v2の概要やリリース背景を理解する ● 新しいreflection機能の使い方や使い道を理解する

Slide 3

Slide 3 text

Agenda 1. Introduction 2. What’s Protocol Buffers? 3. What’s Go Protocol Buffers API v2? 1. Faults in v1 2. What v2 provides 4. Examples using protoreflect 1. Custom regulations for String 2. Random message struct generator 3

Slide 4

Slide 4 text

$whoami ● Ryoya Sekino /関野 涼也 ● Software Engineer at UPSIDER, inc., leading Card Processing team ● Writing Go for 2 years as a main language ● Loves music, DJ’ing 4 1. Introduction sekino_pii sryoya

Slide 5

Slide 5 text

Briefly about UPSIDER ● 成長企業向けの法人カードを提供しているスタートアップです ⭐ ● 金融SaaSとして企業のお金周りの課題を解決することを目指してい ます 🏢 5 1. Introduction

Slide 6

Slide 6 text

成長フェーズにつき、絶賛採用中です!! ● 成長企業向けの法人カードを提供しているスタートアップです ⭐ ● 金融SaaSとして企業のお金周りの課題を解決することを目指してい ます 🏢 ● Tech Stacks: Go, Kotlin, k8s, Istio, microservices ● Working Styles: フルリモート、フルフレックス、業務委託可、副業可 6 1. Introduction 問い合わせはこちらまで https://corporatecard.up-sider.jp/career Gopherの原著作者は Renée Frenchさんです。

Slide 7

Slide 7 text

Agenda 1. Introduction 2. What’s Protocol Buffers? 3. What’s Go Protocol Buffers API v2? 1. Faults in v1 2. What v2 provides 4. Examples using protoreflect 1. Custom regulations for String 2. Random message struct generator 7

Slide 8

Slide 8 text

8 2.What’s Protocol Buffers? ● IDL (インターフェース定義言語) で構造を定義し、データを Serialize/Deserializeする仕組み ● 高速でシンプルなのが特徴 ● 言語や環境に依存しないで使用できる  メッセージが各言語の形にコンパイル するツールが提供されている ● RPC(gRPC含む)で利用されている Protocol Buffers (a.k.a., protobuf, pb) は構造化データを Serializeする仕組み & そのインターフェース定義言語

Slide 9

Slide 9 text

message Person { string name = 1; string phone_number = 2; int32 age = 3; bool is_alive = 4; } このようなデータ形式のものを”.proto”という拡張子のファイルに定義する 9 2.What’s Protocol Buffers? 基本のデータ構造はmessageという単位で表現する 右端のタグ番号は、 Serializing用のフィールド識別子

Slide 10

Slide 10 text

protobufには、各言語から操作できるようなAPIが用意されて いる ● protoc コンパイラが各言語の表現形式に変換する https://github.com/protocolbuffers/protobuf ● 対応言語はたくさん Go, C#, C++, Dart, Java, Kotlin, Node, Objective-C, PHP, Python, Ruby ● Goでは、コンパイルすると、pb.goというファイルに変換される 10 2.What’s Protocol Buffers? .proto .pb.go コンパイル

Slide 11

Slide 11 text

11 2.What’s Protocol Buffers? Goにコンパイルするとmessageがstructとして表現される message Person { string name = 1; string phone_number = 2; int32 age = 3; bool is_alive = 4; } type Person struct { Name   string PhoneNumber string Age    int32 IsAlive bool } コンパイル .pb.go コンパイル .proto

Slide 12

Slide 12 text

12 2.What’s Protocol Buffers? protobufをGoの表現形式で操作するAPIが今回のお題 Gopherの原著作者は Renée Frenchさんです。 message Person { string name = 1; string phone_number = 2; int32 age = 3; bool is_alive = 4; }

Slide 13

Slide 13 text

13 2.What’s Protocol Buffers? このセッションでのProtocol Buffers関連の言葉の使い方 Protocol Buffers (protobuf, pb) : Serializingフォーマット、またはそのIDLのこと。 (protobufの) Message: protobufのIDLで定義されたメッセージ、またはそれの具 体的なデータのこと Proto File: protobufのIDLを定義したファイル(.proto)のこと Note: これらは必ずしも厳密な言葉の定義とは一致しません。

Slide 14

Slide 14 text

Agenda 1. Introduction 2. What’s Protocol Buffers? 3. What’s Go Protocol Buffers API v2? 1. Faults in v1 2. What v2 provides 4. Examples using protoreflect 1. Custom regulations for String 2. Random message struct generator 14

Slide 15

Slide 15 text

● Goのreflect packageがGoのデータ形式に従ったreflectionを提供するように、 protobufのデータ形式に沿ったreflectionを提供 ● Interfaceを介して、protobufのデータ操作の手段を共通化・充実化 15 3. What’s Go Protocol Buffers API v2? Go Protocol Buffers API v2は、interfaceの実装を充実さ せ、protobufのデータ形式の沿ったreflection機能を提供

Slide 16

Slide 16 text

Agenda 1. Introduction 2. What’s Protocol Buffers? 3. What’s Go Protocol Buffers API v2? 1. Faults in v1 2. What v2 provides 4. Examples using protoreflect 1. Custom regulations for String 2. Random message struct generator 16

Slide 17

Slide 17 text

1. Messageに対して、protobuf Messageとしてのreflectionが実行しづらい 2. Messageのinterfaceが簡素なため、Messageに対する共通の処理を実行し づらい 3. デフォルトのコンパイラ以外で生成した protobufのGoの表現形式も共通の処 理ができるようにしたい 17 3-1. What’s Go Protocol Buffers API v2? - Faults in v1 v1には、Messageの情報操作やinterfaceに課題があった

Slide 18

Slide 18 text

● Goのreflect パッケージはあくまで、GoのTypeとしてしか扱えないので、 protobufのMessageをprotobufの文法に則って扱いたい ● Messageの情報を取得する方法はあるが、簡単に操作するような方法が公式 で与えられていない 18 3-1. What’s Go Protocol Buffers API v2? - Faults in v1 v1の課題1/3: Messageに対して、protobuf Messageとして のreflectionが実行しづらい func (*DoResponse) Descriptor() ([]byte, []int) { // ... } Byteで返ってくる

Slide 19

Slide 19 text

Messageのinterface自体は特になにもしてない。。。 19 3-1. What’s Go Protocol Buffers API v2? - Faults in v1 v1の課題2/3: Messageのinterfaceが簡素で、Messageに 対する共通の処理を実行しづらい 生成されたstructでも、特に何もしてない type Message interface { Reset() String() string ProtoMessage() } func (*DoRequest) ProtoMessage() {}

Slide 20

Slide 20 text

● protocで生成したメッセージはあくまで、 protobufのGoでの表現形式の一つに すぎないので、独自のcompiler等を使用した独自の表現形式でも reflectionを したい ● CLIなどでGoにコンパイルされたコードが手に入らない状況でも Protocol Buffersのメッセージを扱いたい 20 3-1. What’s Go Protocol Buffers API v2? - Faults in v1 v1の課題3/3: デフォルトのコンパイラ以外で生成した protobufのGoの表現形式も共通の処理ができるようにしたい

Slide 21

Slide 21 text

Agenda 1. Introduction 2. What’s Protocol Buffers? 3. What’s Go Protocol Buffers API v2? 1. Faults in v1 2. What v2 provides 4. Examples using protoreflect 1. Custom regulations for String 2. Random message struct generator 21

Slide 22

Slide 22 text

● Messageのinterfaceが、明示的に、reflection用のinterfaceを返すような関数 を宣言するようになった ● protoreflect packageがprotobufに対して共通のreflectionを実装している 22 3-2. What’s Go Protocol Buffers API v2? - What v2 provides v2では、interfaceを充実させて、interfaceに対するreflection を提供することで、v1の課題を解決した

Slide 23

Slide 23 text

package “google.golang.org/protobuf/proto” package “google.golang.org/protobuf/reflect/protoreflect” type ProtoMessage interface{ ProtoReflect() Message } 23 3-2. What’s Go Protocol Buffers API v2? - What v2 provides v2のproto.Message interfaceは明示的にprotoreflectの interfaceを返す関数を宣言している リフレクション用のinterfaceをを返す type Message = protoreflect.ProtoMessage

Slide 24

Slide 24 text

package “google.golang.org/protobuf/proto” package “google.golang.org/protobuf/reflect/protoreflect” func (x *DoRequest) ProtoReflect() protoreflect.Message { // … omitted ... } 24 3-2. What’s Go Protocol Buffers API v2? - What v2 provides protobufから生成されたmessage structから、reflection用 のinterfaceを実装したtypeを取得できる type ProtoMessage interface{ ProtoReflect() Message } type Message = protoreflect.ProtoMessage

Slide 25

Slide 25 text

25 3-2. What’s Go Protocol Buffers API v2? - What v2 provides protoreflect.MessageがReflection用のメソッドを定義してい る

Slide 26

Slide 26 text

.proto ファイルに定義される情報をDescriptorというinterfaceで抽象的に表現して、 共通の動的な操作を可能にしている 26 3-2. What’s Go Protocol Buffers API v2? - What v2 provides protoreflect packageは、Messageに対する共通の reflection処理を規定している

Slide 27

Slide 27 text

27 3-2. What’s Go Protocol Buffers API v2? - What v2 provides protoファイルのデータ単位ごとにDescriptorが存在している ● FileDescriptor ● ServiceDescriptor ● MethodDescriptor ● MessageDescriptor ● FieldDescriptor ● OneOfDescriptor ● EnumDescriptor ● EnumValueDescriptor

Slide 28

Slide 28 text

28 3-2. What’s Go Protocol Buffers API v2? - What v2 provides Message DescriptorがMessageに対する操作を提供する

Slide 29

Slide 29 text

29 3-2. What’s Go Protocol Buffers API v2? - What v2 provides Field DescriptorがFieldに対する操作を提供する

Slide 30

Slide 30 text

30 3-2. What’s Go Protocol Buffers API v2? - What v2 provides FileDescriptorがファイル全体に対する操作を提供する

Slide 31

Slide 31 text

31 3-2. What’s Go Protocol Buffers API v2? - What v2 provides 同様にその他のデータ単位のDescriptorがある

Slide 32

Slide 32 text

32 3-2. What’s Go Protocol Buffers API v2? - What v2 provides データ単位同士の関係に則って、Descriptorを行ったり来たり できる File Descriptor Service Descriptor Method Descriptor Message Descriptor Field Descriptor Enum Descriptor OneOf Descriptor Enum Value Descriptor

Slide 33

Slide 33 text

33 3-2. What’s Go Protocol Buffers API v2? - What v2 provides GoのMessage Structがあれば、MessageDescriptorを始点 にすべてのDescriptorにアクセスできる File Descriptor Service Descriptor Method Descriptor Message Descriptor Field Descriptor Enum Descriptor OneOf Descriptor Enum Value Descriptor Message type Person struct { Name   string PhoneNumber string Age    int32 IsAlive bool } Proto Message

Slide 34

Slide 34 text

Agenda 1. Introduction 2. What’s Protocol Buffers? 3. What’s Go Protocol Buffers API v2? 4. Examples using protoreflect 1. Custom regulations for String 2. Random message struct generator 34

Slide 35

Slide 35 text

1. Custom regulations for String protoreflectを使ったデータ構造や値の取り出し方の雰囲気 2. Random message struct generator protoreflectを使ったデータの作成・値の書き込み方法の雰囲気 最終形はGitHubに置いてます https://github.com/sryoya/protoreflect-go-examples 35 4. Examples using protoreflect Exampleを通して理解すること

Slide 36

Slide 36 text

Agenda 1. Introduction 2. What’s Protocol Buffers? 3. What’s Go Protocol Buffers API v2? 4. Examples using protoreflect 1. Custom regulations for String 2. Random message struct generator 36

Slide 37

Slide 37 text

概要 ● protobufのStringのフィールドに長さ・形式等の制約をかけられるようにしたい ○ 文字数が6-12文字の値のみ有効なString ○ アルファベットと数字のみ有効な String ● protobufに制約を定義し、具体的なGoのメッセージの値が形式に沿っているか どうかのバリデーション関数を用意する 使い道の例 ● gRPC Serverがいちいち(内部のロジック的に)想定外の値に対するバリデーショ ンを書かなくてよくする ● gRPC Clientがサーバー側の内情を知らなくても、送ろうとしているメッセージが 正しいか判断できるようにする 37 4-1. Examples using protoreflect - Custom regulations for String 作るもの: Custom regulations for String

Slide 38

Slide 38 text

1. Stringのフィールドに長さのルールをOptionで付加する 2. Optionで指定した制約に準拠した値かをバリデーションできる 38 4-1. Examples using protoreflect - Custom regulations for String 使い方のイメージ: String with the custom regulations message UpdateAccountIDRequest { string iD = 1 [ (stroptpb.opts) = {min_len : 6, max_len: 12} ]; } msg = &testproto.UpdateAccountIDRequest{ ID: "12345", } err = stropt.Validate(msg) fmt.Println(err) // Output: Field: ID, invalid length, the value must be longer than or equal to 6, but actual: 5 Optionを指定

Slide 39

Slide 39 text

1. Protocol Buffersに共通のField Optionを定義する 2. 関数を作る 1. 関数のIOを定義する 2. Messageの情報を取り出す 3. 各フィールドの情報を取り出す 4. フィールドのOptionをチェックして取り出す 5. フィールドの値をチェックして取り出す 6. 取り出したOptionと値を利用してバリデーションする 39 4-1. Examples using protoreflect - Custom regulations for String ステップ: Custom regulations for String

Slide 40

Slide 40 text

Note: proto3には存在しなかった ”optional”は、Protocol Buffers v.3.12.0で試験的に導入され ました 40 4-1. Examples using protoreflect - Custom regulations for String 1. Protocol Buffersに共通のField Optionを定義する extend google.protobuf.FieldOptions { StringOpts opts = 50000; } message StringOpts { optional int32 len = 1; optional int32 max_len = 2; optional int32 min_len = 3; optional string regexp = 4; } message UpdateAccountIDRequest { string iD = 1 [ (stroptpb.opts) = {len : 10} ]; } 定義する 実際に埋め込める Optionの識別子は50000-99999でないと いけない

Slide 41

Slide 41 text

Inputは、protobuf Messageから生成されたStructならどんな値でも投げ込めるよう にする 41 4-1. Examples using protoreflect - Custom regulations for String 2-1 関数のIOを定義する Messageから生成されたGoのStructに共通のinterface func Validate(pb proto.Message) error { return validate(pb.ProtoReflect()) }

Slide 42

Slide 42 text

func Validate(pb proto.Message) error { return validate(pb.ProtoReflect()) } proto.Messageからreflection用のinterfaceを実装した値を取り出す 42 4-1. Examples using protoreflect - Custom regulations for String 2-2 Messageの情報を取り出す reflection用のinterfaceを実装した情報を取り出す

Slide 43

Slide 43 text

MessageからField Descriptorを取り出して各フィールドを見ていく func validate(m protoreflect.Message) error { md := m.Descriptor() fds := md.Fields() var errs error for k := 0; k < fds.Len(); k++ { fd := fds.Get(k) // validation for each filed } return errs } 43 4-1. Examples using protoreflect - Custom regulations for String 2-3 各フィールドの情報を取り出す この中に具体的なvalidationを書いていく MessageDescriptorを取り出す FieldDescriptorsを取り出す

Slide 44

Slide 44 text

StrOptsがついているフィールドか確認して、ついていれば Optionの中身を取り出す opts := fd.Options().(*descriptorpb.FieldOptions) so, ok := proto.GetExtension(opts, stroptpb.E_Opts).(*stroptpb.StringOpts) if !ok || so == nil { continue } 44 4-1. Examples using protoreflect - Custom regulations for String 2-4: フィールドのOptionをチェックして取り出す Messageから生成されたStruct

Slide 45

Slide 45 text

1. Stringのフィールドか確認 if fd.Kind() != protoreflect.StringKind { continue } 2. protorefect.Messageから具体的な値を取得する (FieldDescriptorはあくまでデータ構造 を取得するものなので、具体的なフィールドの値は得られない ) strVal := m.Get(fd).Interface().(string) 45 4-1. Examples using protoreflect - Custom regulations for String 2-5: フィールドの値をチェックして取り出す Proto用の型リストと比較 protoreflect.Message

Slide 46

Slide 46 text

func validateValue(fieldName protoreflect.Name, opts *stroptpb.StringOpts, v string) error { err = validateLength(opts, v) If err != nil { // error handling } // other validations... return errs } 46 4-1. Examples using protoreflect - Custom regulations for String 2-6: 取り出したOptionと値を利用してバリデーションする func validateLength(opts *stroptpb.StringOpts, v string) error { } 内容ごとのバリデーションの関数に、 Optionと値を渡す

Slide 47

Slide 47 text

● Message: フィールドのtypeがまたMessageだったときに対応させる ● List: StringのListに対応させる ● Map: ValueにStringを持つMapに対応させる 47 4-1. Examples using protoreflect - Custom regulations for String 応用: Composite TypeのFieldに対応させる

Slide 48

Slide 48 text

● Message: フィールドのtypeがまたMessageだったときに対応させる -> フィールドの型で判定し、再帰処理を実行する ● List: StringのListに対応させる   -> 専用のメソッドで判定し、List用のinterfaceに変換して処理する ● Map: ValueにStringを持つMapに対応させる -> 専用のメソッドで判定し、Map用のinterfaceに変換して処理する 48 4-1. Examples using protoreflect - Custom regulations for String 応用: Composite Typeに対応させる

Slide 49

Slide 49 text

フィールドのTypeを見て再帰呼び出しするだけでOK 49 4-1. Examples using protoreflect - Custom regulations for String Message: フィールドのTypeが別のMessageだったときに対 応させる if fd.Kind() == protoreflect.MessageKind { errs = appendErr(errs, validate(m.Get(fd).Message())) continue }

Slide 50

Slide 50 text

専用のメソッドでListかチェックして、List用のinterfaceに変換した上でfor-loopを回 すだけ 50 4-1. Examples using protoreflect - Custom regulations for String List: StringのListに対応させる if fd.IsList() && fd.Kind() == protoreflect.StringKind { strList := m.Get(fd).List() for i := 0; i < strList.Len(); i++ { strVal := strList.Get(i).Interface().(string) errs = appendErr(errs, validateValue(fd.Name(), so, strVal)) } continue } Note: 通常(primitive type)のString用の条件分岐に入らないように注意 ListのTypeは、Listの中に入る値の Typeになる

Slide 51

Slide 51 text

基本的にListと同じだけど、Type判定とloopの回し型が違う 51 4-1. Examples using protoreflect - Custom regulations for String Map: ValueにStringを持つMapに対応させる if fd.IsMap() { strMap := m.Get(fd).Map() strMap.Range(func(mk protoreflect.MapKey, mv protoreflect.Value) bool { strVal, ok := mv.Interface().(string) if !ok { // error handling return false } errs = appendErr(errs, validateValue(fd.Name(), so, strVal)) return true }) continue } Note: Map自体はMessage型になるので、Message型用の条件分岐に入らないように注意 ValueのTypeを確認しにいく Rangeでloopできる

Slide 52

Slide 52 text

52 4-1. Examples using protoreflect - Custom regulations for String Custom regulations for String - Summary このようにProtocol Buffersのデータ定義を読み込んだ処理ができるようになりました 最終形はGitHubにあります https://github.com/sryoya/protoreflect-go-examples/blob/master/stropt/valid ate.go

Slide 53

Slide 53 text

Agenda 1. Introduction 2. What’s Protocol Buffers? 3. What’s Go Protocol Buffers API v2? 4. Examples using protoreflect 1. Custom regulations for String 2. Random message struct generator 53

Slide 54

Slide 54 text

54 4-2. Examples using protoreflect - Random message struct generator 作るもの: Random message struct generator 概要 ● Proto MessageのStructを受け取って、ランダムな値を埋め込んで返す ● Proto MessageのStructならなんでも扱えるようにする 使い道の例 Fuzzing, Performance Test

Slide 55

Slide 55 text

基本: 元のMessageの値にアクセスして書き換える protoreflect.Message Interfaceは値を直接書き換える共通のメソッドを提供してい る 応用: 別のMessage Structを用意して値を設定し、最後に、元の Structマージする dynamicpbという、proto.Messageのinterfaceを実装した動的なtypeを生成できるパッ ケージがある。dynamicpbで生成したMessageは、同じproto.Messageのstructとマージ して値を書き込むことができる。 55 4-2. Examples using protoreflect - Random message struct generator 要点: protoreflectは、Message Structに値を直接書き込む 手段も提供している

Slide 56

Slide 56 text

func EmbedValue(msg proto.Message) error { pm := msg.ProtoReflect() fds := pm.Descriptor().Fields() for k := 0; k < fds.Len(); k++ { fd := fds.Get(k) // need handling for List and Map switch fd.Kind() { case protoreflect.StringKind: // write value   // other types including recursion default: return fmt.Errorf("unexpected type: %v", fd.Kind()) } } // ... } 56 4-2. Examples using protoreflect - Random message struct generator 読み込みは前の例と同じ要領

Slide 57

Slide 57 text

protoreflect.Message interfaceを介して、MessageのStructに書き込める switch fd.Kind() { case protoreflect.Int32Kind: pm.Set(fd, protoreflect.ValueOfInt32(rand.Int31())) // ... default: return fmt.Errorf("unexpected type: %v", fd.Kind()) } 57 4-2. Examples using protoreflect - Random message struct generator 基本: 元のMessageの値にアクセスして値を書き換える Protoreflectの型定義に変換 Fieldに値をセットできる

Slide 58

Slide 58 text

switch fd.Kind() { case protoreflect.MessageKind: // generate its child message pm.Set(fd, protoreflect.ValueofMessage(XXX))) default: return fmt.Errorf("unexpected type: %v", fd.Kind()) } 58 4-2. Examples using protoreflect - Random message struct generator ただし、この方法だと再帰処理などで元のMessageに辿るこ とが面倒な場合がある 親のMessageにセットするために、フィールドの Messageの値を用意しないといけない

Slide 59

Slide 59 text

● dynamicpbは、DescriptorからProtocol BuffersのMessageのStructを作成す るパッケージ https://pkg.go.dev/google.golang.org/protobuf/types/dynamicpb ● dynamicpbで生成した値を、protocコンパイラが生成したMessage Structに マージして値を書き換えることができる 59 4-2. Examples using protoreflect - Random message struct generator 応用: dynamicpbを使えば、Messageの情報から、新規 MessageのTypeを生成できる

Slide 60

Slide 60 text

● Goのコンパイル時点で具体的なGoのStructが手に入らない状況でも、 Protocol Buffersのメッセージを作成できる ○ ex) Protocol Buffersに対する汎用のCLI, カスタムのCompilerなど ● 再帰処理とかで元のMessageのStructを取り出して書き込むのが面倒なときに も、dynamicpbで具体的な値を作って、元のMessageにマージできる ○ 今回のケース(ただし、dynamicpbを使わなくてもやる方法自体はある ) 60 4-2. Examples using protoreflect - Random message struct generator 応用: dynamicpbは、具体的なGoのMessage Structが手に 入らない状況でも、Messageの値が用意できる

Slide 61

Slide 61 text

1. MessageDescriptorを渡すと、Messageの情報を持ったdynamicなMessage Structが作成できる dm := dynamicpb.NewMessage(m.ProtoReflect().Descriptor()) 2. dynamicpbのMessageにも、Proto.Messageと同じように値をセットできる dm.Set(fd, value) 61 4-2. Examples using protoreflect - Random message struct generator 応用: dynamicpbに、Messageの情報を渡して、値を生成さ せる 引数にいれる値は下記の通り 1. フィールドの情報(FieldDescriptor) 2. セットする値

Slide 62

Slide 62 text

これで具体的な値が対象の Structにセットされる proto.Merge(msg, dm) 62 4-2. Examples using protoreflect - Random message struct generator 応用: dynamicpbで生成したStructをProcol Buffersから生 成されたMessage Structにマージする 引数にいれる値は下記の通り 1. セット先のMessage Struct 2. セット元のMessage Struct(dynamic pbが生成した値)

Slide 63

Slide 63 text

最終形はGitHubへ https://github.com/sryoya/protoreflect-go-examples/tree/master/protorand 63 4-2. Examples using protoreflect - Random message struct generator Random message struct generator - Summary

Slide 64

Slide 64 text

● Go Protocol Buffers API v2では、MessageのInterfaceが充実され、 reflectionの機能が提供された ● protoreflectパッケージを利用して、Protocol Buffersのデータ形式に沿った データの読み書きができる 64 まとめ

Slide 65

Slide 65 text

65 Appendix - Go Protocol Buffers API v2のimport path ● google.golang.org/protobuf ○ ちなみにv1はgithub.com/golang/protobuf ● versionはv1.20.0から始まる ○ まだ提供されているv1(2021年4月現在でv1.5.2)がv1.20まで到達するこ とはないだろうかららしい

Slide 66

Slide 66 text

66 Appendix - v2からのGoコード生成ツールと使用例 ● protobufのGoコード生成 ○ google.golang.org/protobuf/cmd/protoc-gen-go ● gRPCのGoコード生成 ○ google.golang.org/grpc/cmd/protoc-gen-go-grpc ● コマンド例 $ find . -name '*.proto' -exec protoc --experimental_allow_proto3_optional -I ./ --go_out . --go_opt paths=source_relative --go-grpc_out . --go-grpc_opt paths=source_relative {}

Slide 67

Slide 67 text

67 Appendix - その他関連パッケージ ● protocmp ○ google.golang.org/protobuf/testing/protocmp ○ go-cmpを内包したテスト用のツール ● protojson ○ google.golang.org/protobuf/encoding/protojson ○ Jsonとprotobufの変換(v1の改良版) ● protogen ○ google.golang.org/protobuf/compiler/protogen ○ protobuf compilerの作成用のヘルパーツール

Slide 68

Slide 68 text

68 Reference ● The Go Blog A new Go API for Protocol Buffers https://blog.golang.org/protobuf-apiv2 ● protoreflect https://pkg.go.dev/google.golang.org/protobuf/reflect/protoreflect ● dynamicpb https://pkg.go.dev/google.golang.org/protobuf/types/dynamicpb

Slide 69

Slide 69 text

EoF Gopherの原著作者は Renée Frenchさんです。 69