DataSet Mapping to JSON for JavaScript client support in RAD Studio 10.2.2

Posted by on in Tutorial

RAD Studio has offered support for JSON in different ways and for a long time. From the JSON system unit (originally part of the DBX space) to the old DataSnap table mapping (also via DBX) and to FireDAC tables to JSON mapping, there are many ways to interact with JSON data structures. However, until the most recent release, we lacked a way to map a dataset to a custom JSON structure -- the FireDAC JSON support produces a FireDAC specific structure, with meta data and record status information.

While this is a gap we already wanted to fill, it become more important to address it now that we are pushing RAD Server (a free deployment license is included with 10.2.2 Enterprise and above) and use it as a backend for ExtJS applications. As you can read in my blog post Implementing AJAX and JSONP Support in RAD Server for ExtJS, while this works the dataset mapping to JSON required writing custom code. Our first step in simplifying the use of Delphi as a backend for JavaScript applications is offering a better way to produce the JSON data from a database table.

While we have build this support for the scenario of using RAD Server, FireDAC, and ExtJS, the same component and technology can be used for any web service architecture written in Delphi and C++Builder (even pure and simple WebBroker), any dataset other than FireDAC, and any JavaScript client. It is a completely open and a fairly flexible solution. But it certainly works great for our specific scenario!

A VCL Application

I'll describe the solution using two demos. The first is a plain VCL application. while the second will be a RAD Server package. This highlights the fact that the solution is fairly general. In the first demo, I have the following components on a form (I know, I should have used a data module...):

This is the configuration of the components:

object EmployeeConnection: TFDConnection Params.Strings = ( 'ConnectionDef=EMPLOYEE') end object EmployeeTable: TFDQuery Connection = EmployeeConnection SQL.Strings = ( 'SELECT * FROM EMPLOYEE') end object FDBatchMoveDataSetReader1: TFDBatchMoveDataSetReader DataSet = EmployeeTable end object FDBatchMoveJSONWriter1: TFDBatchMoveJSONWriter DataDef.Fields = end object FDBatchMove1: TFDBatchMove Reader = FDBatchMoveDataSetReader1 Writer = FDBatchMoveJSONWriter1 Mappings = LogFileName = 'Data.log' end

With this configuration in place, all you need to do to produce the JSON is connect the output to the JSON writer and execute the batch move operation. In this case I've used a stream:

procedure TForm5.Button1Click(Sender: TObject); var sstr: TStringStream; begin sstr := TStringStream.Create; try EmployeeTable.Active := True; FDBatchMoveJSONWriter1.Stream := sstr; FDBatchMove1.Execute; ShowMessage (sstr.DataString); finally sstr.Free; end; end;

Other options are assigning to the writer for the output a JSONWriter (as I'll show shortly) or a JSONArray.

A RAD Server Web Service

For the second demo, the RAD Server demo, I've used the same set of components with the same configuration. In this cases I've added to an EMS package an "employee" resource, and implemented its get operation with the following stream-based code:

procedure TEmployeeResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); var mStream: TMemoryStream; begin mStream := TMemoryStream.Create; AResponse.Body.SetStream(mStream,'application/json', True); FDBatchMoveJSONWriter1.Stream := mStream; FDBatchMove1.Execute; end;

As a better and simpler alternative, I could have used the JSONWriter property. The difference is that rather tha building the entire JSON data structure in the memory stream and later copy it to the HTML response, the data is written directly to the HTML response, reducing the work and the memory consumption:

procedure TEmployeeResource1.Get(const AContext: TEndpointContext; const ARequest: TEndpointRequest; const AResponse: TEndpointResponse); begin FDBatchMoveJSONWriter1.JsonWriter := AResponse.Body.JSONWriter; FDBatchMove1.Execute; end;

In both cases, you'll see an output like the following:

This is only a first initial step of the support we are planning to simplify the use of Delphi and RAD Server as backend for JavaScript and ExtJS applications. More support will be made available soon. Stay tuned.



About
Gold User, Rank: 7, Points: 457
Delphi and RAD Studio Product Manager at Embarcadero.

Comments

  • Eric T26909
    Eric T26909 Thursday, 18 January 2018

    Hi

    Why not just a method on TDataset like "DatasetToJson" which returns the Json?

    I do not see the need for extra components


    Eric

  • Paulo R4458
    Paulo R4458 Wednesday, 3 January 2018

    Uauuuuu, excelent !!!

  • coolday
    coolday Saturday, 16 December 2017

    I can not even read the code, you can not format the code better like other sites ???!!!

  • Please login first in order for you to submit comments
  • Page :
  • 1

Check out more tips and tricks in this development video: