2022/08/12

Creating Modern JSON Configuration Files Using Delphi

English

Recently, EMBT published an interesting article in their official news: "This Is How To Store Cross Platform App Settings In JSON" by the Softacom Information team. This emerging team collects and publishes articles from Delphi enthusiasts worldwide, so it's unclear who the original author is.

The article discusses that in addition to XML (Extensible Markup Language) and INI (Initial) formats, modern cross-platform applications often use JSON for configuration files, with Visual Studio Code as a classic example.

Visual Studio Code Workspace Settings File

The article pointed out that Delphi provides two JSON libraries: JSON Objects Framework and Readers and Writers JSON Framework. The author also mentioned the most widely used alternative open-source option, X-SuperObject, provided by Turkish engineer Onur YILDIZ. It's interesting to note that the JSON Objects Framework provides JSON Marshaling/Un-Marshaling, so what makes it different from X-SuperObject?

Delphi developers are spoiled for choice when it comes to using JSON. Realy?

The author complains that Delphi engineers have been spoiled by the official JSON frameworks. Is that true?

The article points out that Delphi provides two JSON libraries: JSON Objects Framework and Readers and Writers JSON Framework. As an alternative, the author suggests using the widely popular open-source variant X-SuperObject by Turkish engineer Onur YILDIZ. Curiously, JSON Objects Framework provides JSON Marshaling/Un-Marshaling, so how does it differ from X-SuperObject?


Example using JSON Objects Framework

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
TContact = class(TObject)
  public
    Name: string;
    Age: Integer;
    function ToString: string; override;
  end;
 
procedure TForm1.JSONMarshalClick(Sender: TObject);
var
  LContact: TContact;
  oMarshaller: TJSONMarshal;
  crtVal: TJSONValue;
begin
  LContact := TContact.Create; //our custom class
  LContact.Name:='Hello Eden';
  LContact.Age := 20; //fill with some data
  oMarshaller := TJSONMarshal.Create(TJSONConverter.Create); //our engine
  crtVal := oMarshaller.Marshal(LContact); //serialize to JSON
  try
    Memo1.Text := crtVal.ToString; //display
  finally //cleanup
    FreeAndNil(LContact);
    FreeAndNil(oMarshaller);
    crtVal.Free;
  end;
end;

Example execution result using JSON Objects Framework

1
2
3
4
5
6
7
8
{
  "type": "Unit2.TContact",
  "id": 1,
  "fields": {
    "Name": "Hello Eden",
    "Age": 20
  }
}

Example execution result using JSON Objects Framework

The JSON format produced by TObject using the JSON Objects Framework (JOF) is not as intuitive as the one produced by X-SuperObject. Users might need some time to learn the JOF format to manage their configurations.

This has to do with the original purpose of JOF. Around 2009, Delphi 2009 made a transition in DataSnap Framework from XML RPC to JSON RPC. As mentioned earlier, JOF was initially created to serve DataSnap, among other things, such as handling Delphi TObject's strong typing. Therefore, the format produced by JOF is not a weakly-typed compatible JSON format.

Why doesn't JOF produce widely accepted JSON formats?

So, the author's claim that Delphi engineers are spoiled by the two built-in JSON frameworks is not baseless. After getting used to Delphi's native tools, it may be difficult to accept content that deviates from the "Delphi standard."

Creating your desired format using JOF

Knowing that the built-in JOF won't produce a generic JSON format, you can still create your own. Have you heard of TDBXJSONTools? It can be used to convert TDataSet to JSON, so let's add TObject-to-JSON functionality to it!

TDBXJSONToolsHelper adds ObjToJSON functionality

The original example is excellent and deserves a 5-star rating. I modified the example into a VCL project and replaced X-SuperObject usage with JOF, such as in the configuration file loading section:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
procedure TMyProgSettings.LoadFromFile(AFileName: string = '');
var
  LJObj: TJSONObject;
begin
  if AFileName = '' then
    AFileName := GetDefaultSettingsFilename();
 
  if not FileExists(AFileName) then
    Exit;
 
  LJObj := TJSONObject.Create;
  try
    if LJObj.Parse(TFile.ReadAllBytes(AFileName), 0) > 0 then
    begin
      // Magic method from Eden's TDBXJSONToolsHelper unit
      TDBXJSONTools.JsonToObj(LJObj, Self);  
    end;
  finally
    LJObj.Free;
  end;
end;

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
procedure TMyProgSettings.SaveToFile(AFileName: string = '');
var
  Json: string;
begin
  if AFileName = '' then
    AFileName := GetDefaultSettingsFilename();
 
  // Magic method from Eden's TDBXJSONToolsHelper unit
  with TDBXJSONTools.ObjToJSON(Self) do
  begin
    Json := ToJson;
    TFile.WriteAllText(AFileName, Json, TEncoding.UTF8);
    Free;
  end;
end;

Conclusion

Being "spoiled" by JOF is, in my opinion, a blessing. JOF is a framework well worth learning, and X-SuperObject offers even more features for JSON writing. If you frequently need to write JSON objects, X-SuperObject will definitely win your heart. Additionally, I enjoyed the original author's example of a login process using a while loop to control the login window; it's a great concept to learn.

You can download the TDBXJSONToolsHelper and VCL example program from my Github website: https://github.com/Eden5Wu/HelperClass/tree/master/Demo-JSON/JsonMarshalling

In summary, both the JSON Objects Framework (JOF) and X-SuperObject have their own unique advantages when working with JSON in Delphi. Developers should choose between them based on their specific needs and preferences.

For developers familiar with the Delphi style, JOF provides a familiar environment for working with JSON. However, if you need more control over JSON object writing, then X-SuperObject may be a better choice.

In any case, exploring and learning about the different JSON frameworks available is essential. By understanding their strengths and weaknesses, you can make more informed decisions about which tools to use in your projects.

Remember, practice and experimentation are key to becoming proficient in any programming language or framework. Therefore, don't be afraid to try different approaches and learn from the examples and experiences of other developers in the Delphi community.

中文版:使用 Delphi 寫出現代化 JSON 格式的設定檔案

最近 EMBT 官方新聞出現我很感興趣的文章:This Is How To Store Cross Platform App Settings In JSON,是由 Softacom Information 團隊執筆,這是一個新興團隊,匯整來自全球各地 Delphi 愛好者的文章並發表,所以還不知道真實原作者是誰。

原文作者說明在跨平台應用程式在讀寫設定檔時,除了 XML (Extensible Markup Language) 和 INI (Initial) 外,還有一個現代化應用程式常使用的設定檔格式:JSON,例如 Visual Studio Code 就是一個經典的參考。

Visual Studio Code 工作區設定檔

Delphi developers are spoiled for choice when it comes to using JSON. Realy?

原作控訴 Delphi 工程師已經被官方 JSON 框架寵壞了 (笑),是真的嗎?

2022/08/01

2022 RAD Studio 品質大廳 (Quality Portal) 使用者手冊

在使用 Delphi 或 C++ Builder 時往往會遇到一些操作不習慣、漏洞 (Bugs) 等問題,以前的 Borland, CodeGear 時期就有品質控制 (QC) 網站,但實際使用上不是連不上就是不知道哪一個才是有在維護的連結,所以會很依賴代理商代為傳遞問題回報的工作,回報者很難得到最快最直接的回應。