Hitachi

Cosminexus V11 BPM/ESB基盤 サービスプラットフォーム 解説


2.13.2 gRPC電文(Protocol Buffers形式)とXML形式の変換

gRPC電文(Protocol Buffers形式)とXML形式データの変換について説明します。

gRPC電文とXML形式データの変換は,protoファイルに定義したgRPC電文のメッセージ構造を基に行います。

〈この項の構成〉

(1) gRPC電文(Protocol Buffers形式)とXML形式データの関係

gRPC電文(Protocol Buffers形式)とXML形式データの関係を次に示します。

表2‒48 gRPC電文(Protocol Buffers形式)とXML形式データの関係

Protocol Buffers形式

XML形式

package "mypackage";

message MyMessage {

子要素

}

<mypackage.MyMessage>

子要素

</mypackage.MyMessage>

gRPC電文のメッセージ構造を定義したprotoファイルで定義した「パッケージ名」と「メッセージ名」を.(ピリオド)で結合し,XMLの要素名とします。

gRPC電文のメッセージ構造を定義したprotoファイルで定義した各フィールド値は,フィールド名をXML要素名とします。XMLの出力内容は,子要素のフィールドタイプによって異なります。

子要素のフィールドタイプごとのXML出力内容を次に示します。

表2‒49 子要素のフィールドタイプごとのXMLの出力内容

フィールドタイプ

XMLの出力内容

double

float

  • 文字列表現(指数表記)

  • NaN

  • INF,-INF

int32

int64

uint32

uint64

sint32

sint64

fixed32

fixed64

sfixed32

sfixed64

文字列表現

bool

  • true

  • false

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スキーマファイル

[図データ]