The JSON Data Binding Wizard

From RAD Studio
Jump to: navigation, search

Go Up to File Menu

File > New > Other... > Delphi > Web > JSON Data Binding

The JSON Data Binding wizard provides an easy way to create Delphi data types based on a JSON data structure and map these types to the JSON data using one of the Delphi JSON marshaling and serialization libraries.

This Wizard guides the developer to set different options to help create a new unit with the data mapping based on an existing JSON data structure used as a blueprint.

Summary: How does it work

The Wizard takes a JSON text, analyzes it, and generates a set of Delphi types.

Because JSON does not have an official or widely used schema definition, the result of the analysis represents the types that best fit the specified JSON data.

The generated code is optimized for a specified JSON library, which you can pick in the Wizard. At this moment, the supported libraries are:

Example

For example, given the JSON data:

{"customer": {
 "id": 1,
 "name": "Mark",
 "phone": "(831) 431-1000"
}}

The Wizard generates the following types for the REST.Json library:

  [JsonSerialize(jmAllPubProps)]
  TCustomer = class(TPersistent)
  private
	Fid: Integer;
	Fname: string;
	Fphone: string;
  public
	property id: Integer read Fid write Fid;
	property name: string read Fname write Fname;
	property phone: string read Fphone write Fphone;
  end;

  [JsonSerialize(jmAllPubProps)]
  TData = class(TPersistent)
  private
	Fcustomer: TCustomer;
  public
	constructor Create;
	destructor Destroy; override;
	property customer: TCustomer read Fcustomer;
  end;

Then, the application may use this library or high-level thin TJSONMapper<T> class to load JSON data into these type instances or to serialize type instances into JSON.

For example, using REST.Json:

  // Load JSON data from “s” string into new TData instance
  LData := TJson.JsonToObject<TData>(s);

  // Serialize TData instance referenced by LData into JSON string
  s := TJson.ObjectToJsonString(LData);

Or using TJSONMapper<T>:

  // Set JSON library to use
  TJSONMapper<TData>.SetDefaultLibrary('REST.Json');

  // Load JSON data from “s” string into new TData instance
  LData := TJSONMapper<TData>.Default.ObjFrom(s);

  // Serialize TData instance referenced by LData into JSON string
  s := TJSONMapper<TData>.Default.ToStr(LData);

Using the JSON Data Binding Wizard

First, you need to open the JSON Data Binding Wizard on File > New > Other... > Delphi > Web > JSON Data Binding.

Then, complete the following steps:

Step 1: Select the JSON source

JSON Data Binding Wizard JSON Source.png

On the JSON Source page, specify the JSON source from which you want to generate Delphi types.

The alternatives are:

  • Paste from Clipboard: Use JSON text already saved on the Clipboard. This option is available only when the clipboard already contains valid JSON text.
  • Enter in Edit box: Allows introducing the JSON text in an editor provided by the Wizard itself.
  • Read from File: The user must provide a file containing JSON text.
  • Get from REST service: Import the JSON text via an HTTP GET request from a URL indicated on the next page.

Step 2: Enter JSON, provide file, or set REST Service

When JSON is not copied from the clipboard, depending on the option selected in the previous step, the user must do one of the following actions:

  • Paste the JSON manually in the edit box.
  • Provide the path of the file containing the JSON text.
  • Enter an endpoint URL, user name, and password.
Note: After pressing the Next button. The Wizard will try to get and parse JSON and show a message box if any errors are discovered.

Step 3: Specify Binding Options

JSON Data Binding Wizard Binding Options.png

On the Binding Options page, specify how to map/bind the JSON elements to Delphi elements. Here, you can pick one of the available mapping libraries and select other settings of the mapping logic.

The options are:

  • JSON mapping library: JSON marshaling/serialization library, for which the Delphi types must be generated. Options are:
    • System.JSON.Serializers
    • REST.Json
  • Map JSON array to: The Delphi data type that will be used to map JSON array. Possible options are:
    • TArray
    • TList (some JSON libraries, like REST.Json, may not support “TList” mapping to JSON arrays directly).
  • Map JSON object to: The Delphi data type that will be used to map JSON objects. Possible options are:
    • TObject
    • record (some JSON libraries, like REST.Json, may not support “record” type.
  • Map JSON member to: The Delphi data type that will be used to map JSON object members. Possible options are:
    • property
    • field
  • Map JSON string to: The Delphi data type that will be used to map JSON string values. Possible options are:
    • Unicode
    • Ansi
  • Property accessors: These options determine the code of the class being generated. Possible options are:
    • fields
    • Getters
    • Setters
    • Getters and Setters
    Note: The JSON information is mapped to fields via properties, but you can ask these properties to be mapped to fields directly, to a field when reading, and a setter method with writing, the opposite (very uncommon), or to two methods for reading and writing.

Step 4: Select Code Options

JSON Data Binding Wizard Code Options.png

On the Code Options page, specify how to name Delphi entities.

The options are:

  • Base class name: Class name from which all generated entity types will be inherited when on the previous page, the Map JSON object to option is set to TObject (Has no meaning for record).
  • Root object type name: The name of the outermost Delphi entity to which the outermost JSON object will be mapped.
  • Root array type name: Optional. The name of the Delphi entity that will represent the array of “root” entities. When the Root array type name is not specified, the corresponding Delphi entity type is not generated. When specified, then an entity will be generated like this, where is single Dataset property:
[JsonSerialize(jmFields)]
TDataArray = class(TPersistent)
private
FDataset: TArray<TData>;
  public
	destructor Destroy; override;
	property Dataset: TArray<TData> read FDataset write FDataset;
  End;

Finally, press the Finish button to generate the source code.

Mapping rules

The JSON Data Binding wizard uses the following data mapping rules:

  • JSON object maps to Delphi TObject or record: The exact type depends on the Map JSON object to setting and the capability of the JSON library to support Delphi records (REST.Json library does not support records).
  • JSON array maps to Delphi TList<T> or TArray<T>: The exact type depends on the Map JSON array to setting and capability of the JSON library to deserialize/serialize Delphi TList<T> from JSON array directly. REST.Json library does not support TList<T>; instead of JSON array, it is mapped to JSON object with nested array.
  • JSON object member maps to a Delphi field or property: The exact kind depends on the Map JSON member to and Map JSON object to settings. Property kind is not supported for the record type.
    • The type of field/property is guessed after analyzing the values in up to 1,000 objects when the JSON objects are collected into a JSON array. The Wizard can specifically handle date and time values, TGUIDs, Booleans, and more.
    • The name of the field/property is equal to the JSON member name, when the last one is a valid Delphi identifier. Otherwise, the name is “modified” to be a valid identifier. The fields additionally are prefixed by the “F” character.
  • The Wizard does the selected JSON library “binding”, including three elements:
    • Adds an attribute to each TObject or record type, specifying which members to use in serialization. For example:
      [JsonSerialize(jmAllPubProps)]
      TCustomer = class(TPersistent)
    
    • Adds an attribute to TObject or record type members when its name differs from the JSON member name. For example:
      [JsonName('label')]
        property label_: string read Flabel_ write Flabel_;
    
    • Adds a library unit where the above attributes are declared to the generated unit uses clause. For example:
      uses
        System.Classes, REST.Json.Types;
    
Note: The JSON Data Binding wizard uses Data.DBJson.TJSONToDataSetBridge class to analyze the JSON structure and populate Data.DB.TFieldDefs collection. Then, the Wizard uses this collection to generate Delphi types.

How to use the Generated Types

The generated Delphi types may be used with the JSON library that was chosen in the Wizard. No additional changes are required. If it is required to change the library mapping, we recommend running the Wizard again and choosing the required library.

For example, when using REST.Json you get this code:

  // Load JSON data from “s” string into new TData instance
  LData := TJson.JsonToObject<TData>(s);

  // Serialize TData instance referenced by LData into JSON string
  s := TJson.ObjectToJsonString(LData);

The alternative option here is to use the System.JSON.TJSONMapper generic class, which is a thin wrapper of existing JSON libraries. It provides a simplified API for most common JSON serialization/deserialization operations, although it hides options and additional specific APIs provided by the libraries. For example:

  // Set JSON library to use
  TJSONMapper<TData>.SetDefaultLibrary('REST.Json');

  // Load JSON data from “s” string into new TData instance
  LData := TJSONMapper<TData>.Default.ObjFrom(s);

  // Serialize TData instance referenced by LData into JSON string
  s := TJSONMapper<TData>.Default.ToString(LData);

For more information, please visit System.JSON.TJSONMappers.

See Also