JSON format spread over the years and became preferred lightweight protocol for data exchange. Delphi natively supports JSON via the classes in the System.JSON unit. But dealing with TJsonObject requires an intermediate layer for mapping JSON values to our business logic.
Recent Delphi releases make it easier to load JSON data to a specific BL class with the help of TJson.JsonToObject. But in all cases the developer should manually create these BL classes which can be time consuming operation. The missing part is the JSON Data binding wizard.
So the JsonToDelphiClass was born. It analyses given JSON string, visualizes it in an easy to read way (in a treeview) and generates corresponding delphi classes (business objects). Just what XML Data binding wizard does for XML.
- Build entirely on the RTL (no external dependencies) so it’s cross-platform;
- Accepts any valid JSON string, no matter how complex the object is;
You can validate JSON strings online.
- Visualizes the structure of the JSON objects in a treeview;
- Generates complete delphi unit (declaration and implementation), based on the JSON string input;
- Automatically prefixes reserved Delphi words with “&” (ampersand);
- Automatically prevents class name collisions by using numeric suffixes;
- * Blocks unit generation if the JSON string contains empty Array;
- Adds support code to automatically destroy complex sub types. So you don’t have to manage subobject’s lifetime manually;
- ** Uses TArray<T> to represent lists;
- Adds helper serialization/deserialization functions;
- Serialization and deserialization results in the same JSON structure!
- Automatically detects date/datetime parts and maps them to TDate/TDateTime (as long as dates are ISO8601 compliant);
- Maps all numbers to Double;
- Maps true/false values to Boolean;
- Allows you to change property names (keys);
- Allows you to change the names of the stub classes;
- All fields in stub classes are sorted alphabetically;
- Supports JSON pretty print to format the input string;
- Simple and responsive GUI;
- *** Automatic check for update, based on ITask (Parallel Programming Library)!
- It’s open source! You can find the source code and binary releases on GitHub;
- The program uses MadExcept to report unhanded exceptions;
* If the JSON array is empty the contained type is unknown. Unit generation works only with known and supported types.
** This is because serialization of TList<T> adds “noise” i.e. includes internal properties that did not exist in the original JSON string.
*** The releases of JsonToDelphiClass (source and binaries) are public and reside on GitHub. The update unit uses GitHub’s REST API to enumerate tags/releases.
I decided to use Firemonkey (XE7). It was a big challenge, because I faced many problems! So this slowed me down because I had to submit QCs i find workarrounds:
Hopefully these QCs will be fixed soon.
Still there are a few nasty bugs, but it’s hard to reproduce them for QC reports:
- At first show the main Popup menu is badly clipped:
- The Treeview changes items’ height when you press Visualize button two or more times;
- One possible issue with MadExcept and Report Resource Leaks feature;
If I have free time I’ll dig into these bugs.
But the final result looks good and should compile for MAC OS!
BTW uGitHub.pas is generated by the JsonToDelphiClass itself 🙂
The idea of automatic update check is not something new to me. I’ve done this hundreds of times before. But this is the first time that I use GitHub for program update purposes. I am pleasantly surprised from what GitHub offers – Releases and REST interface! Which made me play with Delphi REST components. Nice!
This program uses *very simple* check for update mechanism. The user is only notified for new version availability, but do not automatically download the new version!
Git REST API require the use of SSL. This is why I needed to use OpenSSL binaries. And by the way I finally got it to know why the first call to idHTTP.GET is soooo slow (about 3 sec.) with SSL: LoadOpenSSLLibrary calls InitializeRandom. The next call to _RAND_Screen() blocks for about 3 seconds!
This is why the program cannot terminate immediately.
Update checker uses the new Parallel Programming library and especially ITask. The program demonstrates basic ITask usage, GUI responsiveness and clean termination.
The UI is simple and User experience is good enough:
- The UI don’t freeze;
- The treeview supports a PopUp menu that allows you to rename properties and classes. The F2 key also works;
- The JSON string memo supports JSON prettify feature, available through mouse double click or from the context menu;
- The Save Dialog automatically receives the name of the target Delphi unit;
- The Main Form is re-sizable and have minimum constraints set;
- You can horizontally resize the main panels using the splitter;
- You are notified if there is newer version. An additional form shows more details:
- Paste a valid JSON string into the memo. You can prettify it with double click inside the memo;
- Press the “Visualize” button. On the left you will see the future class structure – properties and types;
- Edit the structure if you need to. You can rename properties and classes with right-click or F2;
- Press “Preview Unit” button to see the generated unit;
- Save the generated unit;
IMPORTANT: The generated unit is compatible with Delphi XE5 or later. Backward compatibility is planned.
MEANWHILE if you need to compile the generated units with older versions, please remove/comment out the ToJsonString/FromJsonString and remove Rest.Json and System.Json units from the USES clause.
I was pleasantly surprised to find a review of JsonToDelphiClass here: JSON To Delphi Class Generator Wizard For Delphi XE7 Firemonkey On Android And IOS. Thanks to FMX Express team!
GitHub Project link: https://github.com/PKGeorgiev/Delphi-JsonToDelphiClass
GitHub Releases link: https://github.com/PKGeorgiev/Delphi-JsonToDelphiClass/releases
The archive JsonToDelphiClass-A.BC.zip contains the release version of the program along with libeay32.dll and ssleay32.dll. I plan to play with UPX to further reduce exe size.
Feel free to report any problems/suggestions using GitHub’s facilities.