2.13.2 gRPC電文(Protocol Buffers形式)とXML形式の変換
gRPC電文(Protocol Buffers形式)とXML形式データの変換について説明します。
gRPC電文とXML形式データの変換は,protoファイルに定義したgRPC電文のメッセージ構造を基に行います。
- 〈この項の構成〉
(1) gRPC電文(Protocol Buffers形式)とXML形式データの関係
gRPC電文(Protocol Buffers形式)とXML形式データの関係を次に示します。
Protocol Buffers形式 |
XML形式 |
---|---|
package "mypackage"; message MyMessage { 子要素 … } |
<mypackage.MyMessage> 子要素 … </mypackage.MyMessage> |
gRPC電文のメッセージ構造を定義したprotoファイルで定義した「パッケージ名」と「メッセージ名」を.(ピリオド)で結合し,XMLの要素名とします。
gRPC電文のメッセージ構造を定義したprotoファイルで定義した各フィールド値は,フィールド名をXML要素名とします。XMLの出力内容は,子要素のフィールドタイプによって異なります。
子要素のフィールドタイプごとのXML出力内容を次に示します。
フィールドタイプ |
XMLの出力内容 |
---|---|
double float |
|
int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 |
文字列表現 |
bool |
|
string |
UTF-8文字列 |
bytes |
バイナリデータをbase64変換した文字列 |
enum |
|
map |
|
message |
内包するフィールドのフィールド値の規則に従います。 |
protoファイルでrepeatedが指定されたフィールドは,同一要素名を持つXML要素が連続します。
(2) gRPC電文とXML形式データのマッピング例
相互変換を行うgRPC電文とXML形式データのマッピング例について説明します。
(a) int32型のマッピング例
int32型のマッピング例を次に示します。
- ●protoファイルに定義したProtocol Buffers IDL
package mypackage; message MyMessage { int32 intvar = 1; }
- ●gRPC電文
{ intvar: 100 }
- ●XML文書
<mypackage.MyMessage> <intvar>100</intvar> </mypackage.MyMessage>
(b) bytes型のマッピング例
bytes型のマッピング例を次に示します。
- ●protoファイルに定義したProtocol Buffers IDL
package mypackage; message MyMessage { bytes bytesField = 1; }
- ●gRPC電文
{ bytesField: [0x01,0x02,0x03,0x04] }
- ●XML文書
<mypackage.MyMessage> <bytesField>AQIDBA==</bytesField> </mypackage.MyMessage>
(c) ネストしたメッセージのマッピング例
ネストしたメッセージのマッピング例を次に示します。
- ●protoファイルに定義したProtocol Buffers IDL
package mypackage; message MyMessage { mesage SubMessage { string stringField = 1; } SubMessage messageField = 1; }
- ●gRPC電文
{ messageField: {stringField: "hello"} }
- ●XML文書
<mypackage.MyMessage> <messageField> <stringField>hello</stringField> </messageField> </mypackage.MyMessage>
(d) repeated型のフィールドのマッピング例
repeated型のフィールドのマッピング例を次に示します。
- ●protoファイルに定義したProtocol Buffers IDL
package mypackage; message MyMessage { repeated string stringField = 1; }
- ●gRPC電文
{ stringField: ["hello","goodbye"] }
- ●XML文書
<mypackage.MyMessage> <stringField>hello</stringField> <stringField>goodbye</stringField> </mypackage.MyMessage>
(e) enum型のフィールドのマッピング例
enum型のフィールドのマッピング例を次に示します。
- ●protoファイルに定義したProtocol Buffers IDL
package mypackage; message MyMessage { enum EnumType { ZERO = 0; ONE = 1; ALT_ONE = 1; } EnumType enumField = 1; }
- ●gRPC電文
{ enumField: ZERO }
- ●XML文書
<mypackage.MyMessage> <enumField>ZERO</enumField> </mypackage.MyMessage>
(f) enum型のフィールドのマッピング例(先に定義された列挙子を出力する場合)
enum型のフィールドのマッピング例(先に定義された列挙子を出力する場合)を次に示します。この例では,同一列挙値(=1)のONEおよびALT_ONEの2つの列挙子を定義しているため,定義順が先の列挙子に変換されます。
- ●protoファイルに定義したProtocol Buffers IDL
package mypackage; message MyMessage { enum EnumType { ZERO = 0; ONE = 1; ALT_ONE = 1; } EnumType enumField = 1; }
- ●gRPC電文
{ enumField: ALT_ONE }
- ●XML文書
<mypackage.MyMessage> <enumField>ONE</enumField> </mypackage.MyMessage>
(g) map型のフィールドのマッピング例
map型のフィールドのマッピング例を次に示します。
- ●protoファイルに定義したProtocol Buffers IDL
package mypackage; message MyMessage { map<string, uint32> mapField = 1; }
- ●gRPC電文
{ mapField: [{"key1",1234},{"key2",9999}] }
- ●XML文書
<mypackage.MyMessage> <mapField> <key>key1</key> <value>1234</value> </mapField> <mapField> <key>key2</key> <value>9999</value> </mapField> </mypackage.MyMessage>
(3) proto-XMLスキーマの出力ファイル形式
proto-XMLスキーマの出力ファイル形式を次に示します。
XMLスキーマは,タイプ定義部およびルート要素定義部によって構成されます。
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="メッセージタイプ名" xmlns="メッセージタイプ名" elementFormDefault="qualified"> タイプ定義部[0..n] ルート要素定義部[1..1] </xs:schema>
(a) タイプ定義部
タイプ定義部は0個以上のメッセージ型定義,または列挙型定義によって構成されます。
- ■メッセージ型定義
<xs:complexType name="完全メッセージ型名"> <xs:sequence> 項目定義[1..n] </xs:sequence> </xs:complexType>
「完全メッセージ型名」は,「パッケージ名.[親メッセージタイプ名称.]メッセージタイプ名称」の形式を持つ文字列です。「親メッセージタイプ名」の部分は,再帰的に適用されます。
- ■列挙型定義
<xs:simpleType name="完全列挙型名"> <xs:restriction base="xs:string"> 列挙値定義[1..n] </xs:restriction> </xs:simpleType>
「完全列挙型名」は,「パッケージ名.[親メッセージタイプ名称.]列挙型」の形式を持つ文字列です。「親メッセージタイプ名」の部分は再帰的に適用されます。
「列挙値定義」は,次の内容で生成されます。
<xs:enumeration value="列挙値"/>
(b) ルート要素定義部
ルート要素定義部は次の内容で生成されます。
<xs:element name="ルート要素名" type="ルート要素タイプ"/>
「ルート要素名」および「ルート要素タイプ」は,「パッケージ名.メッセージタイプ名称」の形式を持つ文字列です。
(c) 項目定義
項目定義は単純項目定義,およびONEOF定義のどちらかで生成されます。
- ■単純項目定義
-
単純項目定義は次の内容で生成されます。
-
repeatedが指定されていない場合
<xs:element name="項目名" type="タイプ名" minOccurs="0"/>
-
repeatedが指定されている場合
<xs:element name="項目名" type="タイプ名" minOccurs="0" maxOccurs="unbounded"/>
「タイプ名」の一覧を次に示します。
表2‒50 単純項目定義のタイプ名一覧 protoファイルに定義した項目のタイプ名
生成されるXMLスキーマの項目のタイプ名
string
xs:string
bytes
xs:base64Binary
int32
xs:int
sint32
sfixed32
int64
xs:long
sint64
sfixed64
uint32
xs:unsignedInt
fixed32
uint64
xs:unsignedLong
fixed64
bool
xs:boolean
float
xs:float
double
xs:double
型参照
メッセージ型名,または列挙型名
-
- ■ONEOF定義
-
ONEOF定義は,次の内容で生成されます。
<xs:element name="ONEOF名"> <xs:complexType> <xs:choice> 項目定義[1..n] </xs:choice> </xs:complexType> </xs:element>
「項目定義」内のminOccurs属性は出力されません。
(d) XMLスキーマ変換例
ここでは,protoファイルからXMLスキーマを生成した場合の変換例について説明します。
- ■例1 すべてのメッセージタイプの一括変換
-
descriptor setファイル内に定義されたすべてのrpcが使用するメッセージタイプのXMLスキーマを生成する場合の変換例を次に示します。
●Descriptor Setファイルの作成に使用したprotoファイル
syntax = "proto3"; option java_multiple_files = true; option java_package = "io.grpc.examples.sampledata"; option java_outer_classname = "SampleDataProto"; option objc_class_prefix = "HLW"; package sampledata; // サービス定義 service UserInfoManager { rpc GetUserInfo (UserInfo) returns (UserData) {} rpc UpdateUserInfo (UserData) returns (UserData) {} } service ProductInfoManager { rpc UpdateProductInfo (ProductData) returns (ProductData) {} } // リクエストまたはレスポンスメッセージ message UserInfo { string userid = 1; } message UserData { string name = 1; string age = 2; } message ProductData { string name = 1; string price = 2; }
●生成されたXMLスキーマファイル
・UserInfo
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="sampledata.UserInfo" xmlns="sampledata.UserInfo" elementFormDefault="qualified"> // タイプ定義部 <xs:complexType name="sampledata.UserInfo"> <xs:sequence> <xs:element name="userid" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> // ルート要素定義部 <xs:element name="sampledata.UserInfo" type="sampledata.UserInfo"/> </xs:schema>
・UserData
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="sampledata.UserData" xmlns="sampledata.UserData" elementFormDefault="qualified"> // タイプ定義部 <xs:complexType name="sampledata.UserData"> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="0" /> <xs:element name="age" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> // ルート要素定義部 <xs:element name="sampledata.UserData" type="sampledata.UserData"/> </xs:schema>
・ProductData
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="sampledata.ProductData" xmlns="sampledata.ProductData" elementFormDefault="qualified"> // タイプ定義部 <xs:complexType name="sampledata.ProductData"> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="0" /> <xs:element name="price" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> // ルート要素定義部 <xs:element name="sampledata.ProductData" type="sampledata.ProductData"/> </xs:schema>
- ■例2 特定のサービスが使用するメッセージタイプの変換
-
引数で指定したサービスに定義された,すべてのrpcが使用するメッセージタイプのXMLスキーマを生成する場合の変換例を次に示します。
●Descriptor Setファイルの作成に使用したprotoファイル
例2のDescriptor Setファイルの作成に使用したprotoファイルは,例1と同じです。
●生成されたXMLスキーマファイル
・UserInfo
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="sampledata.UserInfo" xmlns="sampledata.UserInfo" elementFormDefault="qualified"> // タイプ定義部 <xs:complexType name="sampledata.UserInfo"> <xs:sequence> <xs:element name="userid" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> // ルート要素定義部 <xs:element name="sampledata.UserInfo" type="sampledata.UserInfo"/> </xs:schema>
・UserData
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="sampledata.UserData" xmlns="sampledata.UserData" elementFormDefault="qualified"> // タイプ定義部 <xs:complexType name="sampledata.UserData"> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="0" /> <xs:element name="age" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> // ルート要素定義部 <xs:element name="sampledata.UserData" type="sampledata.UserData"/> </xs:schema>
- ■例3 特定のサービスの中のrpcが使用するメッセージタイプの変換
-
引数で指定したrpcが使用するメッセージタイプのXMLスキーマを生成する場合の変換例を次に示します。
●生成されたXMLスキーマファイル
・ProductData
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="sampledata.ProductData" xmlns="sampledata.ProductData" elementFormDefault="qualified"> // タイプ定義部 <xs:complexType name="sampledata.ProductData"> <xs:sequence> <xs:element name="name" type="xs:string" minOccurs="0" /> <xs:element name="price" type="xs:string" minOccurs="0" /> </xs:sequence> </xs:complexType> // ルート要素定義部 <xs:element name="sampledata.ProductData" type="sampledata.ProductData"/> </xs:schema>
- ■例4 google/protobuf/struct.protoから作成したDescriptor Setファイルを基に生成した場合の変換例
-
Googleがサポートしているgoogle/protobuf/struct.protoから作成したDescriptor Setファイルを基に,XMLスキーマを生成した場合の変換例を次に示します。
なお,メッセージタイプの変換例のため,サービスの定義は省略します。
●struct.proto
●生成されたXMLスキーマファイル