JSON アダプタの使用
JSON アダプタは、ObjectScript オブジェクト (登録、シリアル、または永続) を JSON テキストまたはダイナミック・エンティティにマップするための手段です。この章では、以下の項目について説明します。
-
エクスポートとインポート — JSON 対応のオブジェクトを紹介し、%JSON.AdaptorOpens in a new tab のインポート・メソッドとエクスポート・メソッドを示します。
-
パラメータを使用したマッピング — オブジェクト・プロパティを JSON フィールドに変換する方法を制御するプロパティ・パラメータについて説明します。
-
XData マッピング・ブロックの使用 — 複数のパラメータ・マッピングを 1 つのクラスに適用する方法について説明します。
-
JSON のフォーマット — %JSON.FormatterOpens in a new tab を使用して JSON 文字列をフォーマットする方法を示します。
-
%JSON のクイック・リファレンス — この章で解説したそれぞれの %JSON クラス・メンバについて簡単に説明します。
エクスポートとインポート
JSON との間でシリアル化するクラスは、%JSON.AdaptorOpens in a new tab のサブクラスを作成する必要があります。これには以下のクラスが含まれます。
-
%JSONExport() は、JSON 対応のクラスを JSON ドキュメントとしてシリアル化し、それを現在のデバイスに書き込みます。
-
%JSONExportToStream() は、JSON 対応のクラスを JSON ドキュメントとしてシリアル化し、それをストリームに書き込みます。
-
%JSONExportToString() は、JSON 対応のクラスを JSON ドキュメントとしてシリアル化し、それを文字列として返します。
-
%JSONImport() は、文字列またはストリームとしての JSON か、%DynamicAbstractObjectOpens in a new tab のサブクラスをインポートし、JSON 対応のクラスのインスタンスを返します。
これらのメソッドを示すために、このセクションの例では以下の 2 つのクラスを使用します。
Class Model.Event Extends (%Persistent, %JSON.Adaptor)
{
Property Name As %String;
Property Location As Model.Location;
}
および
Class Model.Location Extends (%Persistent, %JSON.Adaptor)
{
Property City As %String;
Property Country As %String;
}
ご覧のように、場所にリンクする永続イベント・クラスがあります。どちらのクラスも %JSON.AdaptorOpens in a new tab を継承します。これにより、オブジェクト・グラフを生成し、それを JSON 文字列として直接エクスポートすることができます。
set event = ##class(Model.Event).%New()
set event.Name = "Global Summit"
set location = ##class(Model.Location).%New()
set location.Country = "United States of America"
set event.Location = location
do event.%JSONExport()
このコードは、以下の JSON 文字列を表示します。
{"Name":"Global Summit","Location":{"City":"Boston","Country":"United States of America"}}
%JSONExport() の代わりに %JSONExportToString() を使用することで、この JSON 文字列を変数に割り当てることができます。
do event.%JSONExportToString(.jsonEvent)
最後に、%JSONImport() を使用して、このプロセスを逆にたどり、JSON 文字列を再びオブジェクトに変換することができます。この例は、前の例の文字列変数 jsonEvent を取り、それを再び Model.Event オブジェクトに変換します。
set eventTwo = ##class(Model.Event).%New()
do eventTwo.%JSONImport(jsonEvent)
write eventTwo.Name,!,eventTwo.Location.City
これにより、以下のような出力が表示されます。
Global Summit
Boston
インポートとエクスポートはどちらも、どのような入れ子構造でも機能します。
パラメータを使用したマッピング
対応するパラメータを設定することにより、個々のプロパティのマッピング・ロジックを指定できます (%XML.AdaptorOpens in a new tab を使い慣れている場合、これは同様のプロセスです)。
プロパティ・パラメータを指定することにより、Model.Event クラス (前のセクションで定義したもの) のマッピングを変更できます。
Class Model.Event Extends (%Persistent, %JSON.Adaptor)
{
Property Name As %String(%JSONFIELDNAME = "eventName");
Property Location As Model.Location(%JSONINCLUDE = "INPUTONLY");
}
このマッピングによって、以下の 2 つの点が変更されます。
-
プロパティ Name は、eventName という名前の JSON フィールドにマップされます。
-
Location プロパティは、%JSONImport() では引き続き入力として使用されますが、%JSONExport() や他のエクスポート・メソッドでは無視されます。
前述の例では、変更されていない Model.Event クラスのインスタンスで %JSONExport() が呼び出され、以下の JSON 文字列が返されていました。
{"Name":"Global Summit","Location":{"City":"Boston","Country":"United States of America"}}
再マップされた Model.Event のインスタンスで (同じプロパティ値を使用して) %JSONExport() を呼び出すと、以下の文字列が返されます。
{"eventName":"Global Summit"}
以下のようなさまざまなパラメータを使用して、マッピングを調整できます。
-
%JSONFIELDNAME (プロパティのみ) では、JSON コンテンツでフィールド名として使用する文字列を設定します (既定では、値はプロパティ名です)。
-
%JSONIGNOREINVALIDFIELD では、JSON 入力に含まれている予期しないフィールドの処理を制御します。
-
%JSONIGNORENULL を使用すると、開発者は、文字列プロパティの空文字列の既定の処理をオーバーライドすることができます。
-
%JSONINCLUDE (プロパティのみ) では、そのプロパティを JSON の出力または入力に含めるかどうかを指定します (有効な値は "inout" (既定値)、"outputonly"、"inputOnly"、または "none" です)。
-
%JSONNULL では、文字列プロパティについて空の文字列を格納する方法を指定します。
-
%JSONREFERENCE では、オブジェクト参照を JSON フィールドに投影する方法を指定します。オプションは "OBJECT" (既定値)、"ID"、"OID"、および "GUID" です。
詳細は、この章の後述のリファレンス・セクション “%JSON.Adaptor のクラス・パラメータとプロパティ・パラメータ” を参照してください。
XData マッピング・ブロックの使用
プロパティ・レベルでマッピング・パラメータを設定する代わりに、特殊な XData マッピング・ブロック内でマッピングを指定し、インポート・メソッドまたはエクスポート・メソッドを呼び出すときにそのマッピングを適用することができます。
以下のコードでは、前の 2 つのセクションで使用した Model.Event クラスの別のバージョンを定義します。このバージョンでは、プロパティ・パラメータを指定するのではなく、前のバージョンのプロパティと同じパラメータ設定を指定する OnlyLowercaseTopLevel という名前の XData マッピング・ブロックを定義します。
Class Model.Event Extends (%Persistent, %JSON.Adaptor)
{
Property Name As %String;
Property Location As Model.Location;
XData OnlyLowercaseTopLevel
{
<Mapping xmlns="http://www.intersystems.com/jsonmapping">
<Property Name="Name" FieldName="eventName"/>
<Property Name="Location" Include="INPUTONLY"/>
</Mapping>
}
}
重要な違いとして、XData ブロックの JSON マッピングによって既定の動作が変更されるわけではなく、インポート・メソッドとエクスポート・メソッドのオプションの %mappingName パラメータでブロック名を指定することによって、マッピングを適用できるという点があります。以下に例を示します。
do event.%JSONExport("OnlyLowercaseTopLevel")
これにより、以下のような出力が表示されます。
{"eventName":"Global Summit"}
この出力は、プロパティ定義でパラメータを指定した場合と同じです。
指定した名前の XData ブロックがない場合は、既定のマッピングが使用されます。この手法では、複数のマッピングを構成し、それぞれの呼び出しに必要なマッピングを個々に参照することができるため、さらに詳細な制御が可能になると同時に、マッピングの柔軟性と再利用性が向上します。
XData マッピング・ブロックの定義
JSON 対応のクラスでは、任意の数の追加マッピングを定義できます。それぞれのマッピングは、以下の形式の別個の XData ブロックで定義します。
XData {MappingName}
{
<Mapping {ClassAttribute}="value" [...] xmlns="http://www.intersystems.com/jsonmapping".>
<{Property Name}="PropertyName" {PropertyAttribute}="value" [...] />
[... more Property elements]
</Mapping>
}
{MappingName}、{ClassAttribute}、{Property Name}、および {PropertyAttribute} の定義は以下のとおりです。
-
MappingName
%JSONREFERENCE パラメータまたは Reference 属性で使用されるマッピングの名前。
-
ClassAttribute
マッピングのクラス・パラメータを指定します。以下のクラス属性を定義できます。
-
Mapping — 適用する XData マッピング・ブロックの名前。
-
IgnoreInvalidField — クラス・パラメータ %JSONIGNOREINVALIDFIELD を指定します。
-
Null — クラス・パラメータ %JSONNULL を指定します。
-
IgnoreNull — クラス・パラメータ %JSONIGNORENULL を指定します。
-
Reference — クラス・パラメータ %JSONREFERENCE を指定します。
-
-
PropertyName
マッピングされるプロパティの名前。
-
PropertyAttribute
マッピングのプロパティ・パラメータを指定します。以下のプロパティ属性を定義できます。
-
FieldName — プロパティ・パラメータ %JSONFIELDNAME を指定します (既定では、プロパティ名と同じ)。
-
Include — プロパティ・パラメータ %JSONINCLUDE を指定します (有効な値は "inout" (既定値)、"outputonly"、"inputOnly"、または "none" です)。
-
Mapping — オブジェクト・プロパティに適用するマッピング定義の名前。
-
Null — クラス・パラメータ %JSONNULL をオーバーライドします。
-
IgnoreNull — クラス・パラメータ %JSONIGNORENULL をオーバーライドします。
-
Reference — クラス・パラメータ %JSONREFERENCE をオーバーライドします。
-
JSON のフォーマット
%JSON.FormatterOpens in a new tab は、非常に単純なインタフェースを備えたクラスです。このクラスを使用して、ダイナミック・オブジェクト、動的配列、および JSON 文字列をフォーマットして、人が読みやすい形式で表すことができます。すべてのメソッドがインスタンス・メソッドなので、常に、最初にインスタンスを取得します。
set formatter = ##class(%JSON.Formatter).%New()
これを選択する理由は、行ターミネータとインデントに特定の文字 (例えば、空白とタブ。このセクションの末尾にあるプロパティ・リストを参照) を使用するようにフォーマッタを一度構成すれば、後で必要になったときにいつでも使用できるからです。
Format() メソッドは、ダイナミック・エンティティまたは JSON 文字列を取ります。以下は、ダイナミック・オブジェクトを使用した簡単な例です。
dynObj = {"type":"string"}
do formatter.Format(dynObj)
フォーマットされた結果の文字列が現在のデバイスに表示されます。
{
"type":"string"
}
フォーマット・メソッドでは、現在のデバイス、文字列、またはストリームに出力を送信できます。
-
Format() は、指定されたインデントを使用して JSON ドキュメントをフォーマットし、それを現在のデバイスに書き込みます。
-
FormatToStream() は、指定されたインデントを使用して JSON ドキュメントをフォーマットし、それをストリームに書き込みます。
-
FormatToString() は、指定されたインデントを使用して JSON ドキュメントをフォーマットし、それを文字列に書き込むか、JSON 対応のクラスを JSON ドキュメントとしてシリアル化し、それを文字列として返します。
さらに、以下のプロパティを使用して、インデントと改行を制御できます。
-
Indent では、JSON 出力をインデントするかどうかを指定します。
-
IndentChars では、それぞれのインデント・レベルに使用する文字シーケンスを指定します (既定では、レベルごとに 1 つのスペースが使用されます)。
-
LineTerminator では、インデントするときにそれぞれの行を終了する文字シーケンスを指定します。
%JSON のクイック・リファレンス
このセクションでは、この章で解説した %JSON のメソッド、プロパティ、およびパラメータのクイック・リファレンスを提供します。最も包括的な最新情報については、クラス・リファレンスの "%JSON" を参照してください。
%JSON.Adaptor のメソッド
これらのメソッドを使用すると、JSON との間でシリアル化を行うことができます。詳細と例は、“エクスポートとインポート” を参照してください。
%JSON.Adaptor.%JSONExport() は、JSON 対応のクラスを JSON ドキュメントとしてシリアル化し、それを現在のデバイスに書き込みます。
method %JSONExport(%mappingName As %String = "") as %Status
パラメータ :
-
%mappingName (オプション) — Exportポートに使用するマッピングの名前。基本マッピングは "" で表され、これが既定値です。
%JSON.Adaptor.%JSONExportToStream() は、JSON 対応のクラスを JSON ドキュメントとしてシリアル化し、それをストリームに書き込みます。
method %JSONExportToStream(ByRef export As %Stream.Object,
%mappingName As %String = "") as %Status
パラメータ :
-
export — シリアル化された JSON ドキュメントを格納するストリーム。
-
%mappingName (オプション) — エクスポートに使用するマッピングの名前。基本マッピングは "" で表され、これが既定値です。
%JSON.Adaptor.%JSONExportToString() は、JSON 対応のクラスを JSON ドキュメントとしてシリアル化し、それを文字列として返します。
method %JSONExportToString(ByRef %export As %String,
%mappingName As %String = "") as %Status
パラメータ :
-
export — シリアル化された JSON ドキュメントを格納する文字列。
-
%mappingName (オプション) — エクスポートに使用するマッピングの名前。基本マッピングは "" で表され、これが既定値です。
%JSON.Adaptor.%JSONImport() は、JSON またはダイナミック・エンティティの入力をこのオブジェクトにインポートします。
method %JSONImport(input, %mappingName As %String = "") as %Status
パラメータ :
-
input — 文字列またはストリームとしての JSON か、%DynamicAbstractObjectOpens in a new tab のサブクラス。
-
%mappingName (オプション) — インポートに使用するマッピングの名前。基本マッピングは "" で表され、これが既定値です。
%JSON.Adaptor.%JSONNew() は、JSON 対応のクラスのインスタンスを取得します。このクラスのインスタンスを返す前に、カスタム処理 (オブジェクト・インスタンスの初期化など) を実行するようにこのメソッドをオーバーライドできます。ただし、このメソッドをユーザ・コードから直接呼び出さないでください。
classmethod %JSONNew(dynamicObject As %DynamicObject,
containerOref As %RegisteredObject = "") as %RegisteredObject
パラメータ :
-
dynamicObject — 新しいオブジェクトに割り当てられる値を持つダイナミック・エンティティ。
-
containerOref (オプション) — %JSONImport() から呼び出されたときの格納オブジェクト・インスタンス。
%JSON.Adaptor のクラス・パラメータとプロパティ・パラメータ
特に明記していない限り、パラメータは、クラスに対して指定することも、個々のプロパティに対して指定することもできます。クラス・パラメータとして使用する場合は、対応するプロパティ・パラメータの既定値を指定します。プロパティ・パラメータとして使用する場合は、既定値をオーバーライドする値を指定します。詳細と例は、“パラメータを使用したマッピング” を参照してください。
プロパティ変換メソッドの生成を有効にします。
parameter %JSONENABLED = 1;
有効な値は以下のとおりです。
-
1 — (既定値) JSON 対応メソッドが生成されます。
-
0 — メソッド・ジェネレータは、実行可能なメソッドを生成しません。
JSON コンテンツでフィールド名として使用する文字列を設定します。
parameter %JSONFIELDNAME
既定では、プロパティ名が使用されます。
JSON 入力に含まれている予期しないフィールドの処理を制御します。
parameter %JSONIGNOREINVALIDFIELD = 0;
有効な値は以下のとおりです。
-
0 — (既定値) 予期しないフィールドをエラーとして処理します。
-
1 — 予期しないフィールドは無視されます。
文字列プロパティについて空の文字列を格納する方法を指定します。このパラメータは、真の文字列 (XSDTYPE = "string" および JSONTYPE="string" によって指定される) のみに適用されます。
parameter %JSONIGNORENULL = 0;
有効な値は以下のとおりです。
-
0 — (既定値) JSON 入力に含まれる空の文字列は $char(0) として格納され、$char(0) が文字列 "" として JSON に書き込まれます。JSON 入力で指定されていないフィールドは常に "" として格納され、"" は常に、%JSONNULL パラメータに従って JSON に出力されます。
-
1 — 空の文字列と、指定されていない JSON フィールドの両方が "" として入力され、"" と $char(0) の両方がフィールド値 "" として出力されます。
そのプロパティを JSON の出力または入力に含めるかどうかを指定します。
parameter %JSONINCLUDE = "inout"
有効な値は以下のとおりです。
-
"inout" (既定値) — 入力と出力の両方に含めます。
-
"outputonly" — プロパティを入力としては無視します。
-
"inputOnly" — プロパティを出力としては無視します。
-
"none" — プロパティを一切含めません。
指定されていないプロパティの処理を制御します。
parameter %JSONNULL = 0;
有効な値は以下のとおりです。
-
0 — (既定値) 指定されていないプロパティに対応するフィールドは、エクスポート時に無視されます。
-
1 — 指定されていないプロパティは、NULL 値としてエクスポートされます。
オブジェクト参照を JSON フィールドに投影する方法を指定します。
parameter %JSONREFERENCE = "OBJECT";
有効な値は以下のとおりです。
-
"OBJECT" — (既定値) 参照されるクラスのプロパティを使用して、参照オブジェクトを表します。
-
"ID" — 永続クラスまたはシリアル・クラスの ID を使用して、参照を表します。
-
"OID" — 永続クラスまたはシリアル・クラスの OID を使用して、参照を表します。OID は、classname,id という形式で JSON に投影されます。
-
"GUID" — 永続クラスの GUID を使用して、参照を表します。
%JSON.Formatter のメソッドとプロパティ
%JSON.FormatterOpens in a new tab クラスを使用して、JSON 文字列、JSON ストリーム、または %DynamicAbstractObjectOpens in a new tab のサブクラスであるオブジェクトをフォーマットすることができます。詳細と例は、“JSON のフォーマット” のセクションを参照してください。
%JSON.Formatter.Format() は、指定されたインデントを使用して JSON ドキュメントをフォーマットし、それを現在のデバイスに書き込みます。
method Format(input) as %Status
パラメータ :
-
input— 文字列またはストリームとしての JSON か、%DynamicAbstractObjectOpens in a new tab のサブクラス。
%JSON.Formatter.FormatToStream() は、指定されたインデントを使用して JSON ドキュメントをフォーマットし、それをストリームに書き込みます。
method FormatToStream(input, ByRef export As %Stream.Object) as %Status
パラメータ :
-
input — 文字列またはストリームとしての JSON か、%DynamicAbstractObjectOpens in a new tab のサブクラス。
-
export — フォーマットされた JSON ストリーム。
%JSON.Formatter.FormatToString() は、指定されたインデントを使用して JSON ドキュメントをフォーマットし、それを文字列に書き込むか、JSON 対応のクラスを JSON ドキュメントとしてシリアル化し、それを文字列として返します。
method FormatToString(input, ByRef export As %String = "") as %Status
パラメータ :
-
input — 文字列またはストリームとしての JSON か、%DynamicAbstractObjectOpens in a new tab のサブクラス。
-
export (オプション) — フォーマットされた JSON ストリーム。
%JSON.Formatter.Indent プロパティでは、JSON 出力をインデントするかどうかを指定します。既定値は true です。
property Indent as %Boolean [ InitialExpression = 1 ];
%JSON.Formatter.IndentChars プロパティでは、インデントが有効になっている場合にそれぞれのインデント・レベルに使用する文字シーケンスを指定します。既定では、1 つのスペースが使用されます。
property IndentChars as %String [ InitialExpression = " " ];
%JSON.Formatter.LineTerminator プロパティでは、インデントするときにそれぞれの行を終了する文字シーケンスを指定します。既定値は $char(13,10) です。
property LineTerminator as %String [ InitialExpression = $char(13,10) ];