#1 2015-06-25 10:17:30

cypriotcalm
Member
Registered: 2015-02-18
Posts: 122

JSON result on REST request

I have an DTO object and a service:

type
  TMessart = class(TObject)
  private
    FName: TName;
  published
    property Name: TName read FName write FName;
  end;

  TMessarts = array of TMessart;

  initialization
    TJSONSerializer.RegisterObjArrayForJSON(TypeInfo(TMessarts), TMessart);

  ...

  // SERVICE
  function TMessartService.SelectAll(out aMessarts: TMessarts): TCQRSResult;

When I execute an REST request I get some like that:

  http://localhost:7979/root/messartservice/SelectAll
  
  {"result": [[{"ID": 0,"Name": "Messart 1"},{"ID": 0,"Name": "Messart 2"}], 0],"id": 2}

Q1: What are these Zero-IDs? I don't have them in my DTO class.
Q2: Where comes the last zero value in the array from? And what does it mean?
Q3: At each request the "id" is changing. Why and on what purpose?

p.s. sorry for the maybe stupid questions, but I want to fully understand how the framework works! :-)

Last edited by cypriotcalm (2015-06-25 10:41:16)

Offline

#2 2015-06-25 18:11:30

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,207
Website

Re: JSON result on REST request

I suspect you are mixing things.

Inherit TMessart from TSynPersistent.
Your TMessart has no RTTI at all.
So I guess this is another class.

The "id" is the instance ID, of the service implemented on the server side.
So it depends how your service is registered (e.g. sicClientDriven, sicSingle, etc...).

Offline

#3 2015-06-26 04:30:06

cypriotcalm
Member
Registered: 2015-02-18
Posts: 122

Re: JSON result on REST request

ab wrote:

I suspect you are mixing things.

Inherit TMessart from TSynPersistent.
Your TMessart has no RTTI at all.
So I guess this is another class.

I have added the inheritance, but nothing has changed. I have the same output with IDs which are zeros, but I don't have any ID field in the DTO class TMessart defined!? Why do the IDs appear in the result JSON? What things am I mixing?!

Offline

#4 2015-06-26 05:18:57

cypriotcalm
Member
Registered: 2015-02-18
Posts: 122

Re: JSON result on REST request

I rewrited my code as follows:

  // THESE ARE MY DTO TYPES
  TMessart = class(TSynPersistent)
  private
    FName: TName;
  published
    property Name: TName read FName write FName;
  end;

  TMessarts = array of TMessart;

  initialization
    TJSONSerializer.RegisterObjArrayForJSON(TypeInfo(TMessarts), TMessart);
  // THESE ARE MY DAO TYPES
  type
    TDAOMessart = class(TSQLRecord)
    private
      FName: TName;
    published
      property Name: TName read FName write FName;
    end;

    TDAOMessarts = array of TObjectDynArray;

    initialization
      TJSONSerializer.RegisterObjArrayForJSON(TypeInfo(TDAOMessarts), TDAOMessart);
  // SERVICE METHOD
  function TMessartService.SelectAll(out aMessarts: TMessarts): TCQRSResult;
  
  // MESSART COMMAND FACTORY
  constructor TMessartCommandFactory.Create(ARest: TSQLRest; AOwner: TDDDRepositoryRestManager = nil);
  begin
    inherited Create(IMessartService, TMessartService, TDAOMessart, aRest, TDAOMessart, aOwner);
  end;

My messart service method looks like:

function TMessartService.SelectAll(out aMessarts: TMessarts): TCQRSResult;
var
  I: Integer;
  DAOMessarts: TDAOMessarts;
  DTOMessart: TMessart;
begin
  // 1. Select data from the database
  Result := ORMSelectAll('',[]);
  if (Result = cqrsSuccess) then
  begin
    // 2. Get the database data as aggregates, in my case an aggregate is a TSQLRecord class
    Result := ORMGetAllAggregates(PhoDAOMessarts);
    if (Result = cqrsSuccess) then
    begin
      // 3. Initialize the dyn array with the DTO objects and iterate all aggregates
      SetLength(aMessarts, Length(DAOMessarts));
      for I := Low(DAOMessarts) to High(DAOMessarts) do
      begin
        // 4. Create an DTO object for the client output 
        aMessarts[i] := TMessart.Create;
        // 5. Do the "object property conversion", i.e. DTOMessart.Name := DAOMessart.Name
        fDAOConverter.ConvertToDTO(TSQLRecord(DAOMessarts[i]), aMessarts[i]);
      end;
    end;
  end;
end;

On this way my JSON result looks like as expected.

  {"result": [[{"Name": "Messart 1"},{"Name": "Messart 2"}], 0],"id": 2}

Q1: The zero-value doesn't change. What is that value? I have also changed sicSingle, sicShared, sicClientDriven, but the zero-value is still there.
Q2: "id": 2 is changing by each request.

My questions to the code of my service method:
Q3: who and where should be freed the created object in the service method in the step 4? How do I handle properly the memory in that case?

Generally, I am trying to follow the DDD approach like you have described it in the documentation. I'm new to that kind of things.
Q4: What do you think, does my code above fully follow the DDD approach? Or do I mix some things and doing it in a wrong way?

I try to separate the data layer classes (DAOs) and the business domain classes (DTOs), so I do the "object conversion" (see the service method step 5).
Q5: Is it a right and efficient way to do the things like that? Does it make sense to do it? How would you do that?

p.s. sorry for many, and maybe newbie questions, but I'm a new to that kind of stuff and want to learn to do it on the proper way! Thank you for your answers and investing time in that in advance! :-)

Last edited by cypriotcalm (2015-06-26 05:38:30)

Offline

#5 2015-06-26 06:32:09

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,207
Website

Re: JSON result on REST request

Please take the time to read the documentation.
Almost all that you ask is answered there.

About transmission content, see http://synopse.info/files/html/Synopse% … #TITLE_409

Q1. 0 = ord(result)

Q2. id = request/client ID

Q3. http://synopse.info/files/html/Synopse% … l#TITL_154
Objets are allocated by the caller, and freed by the caller, event the "out" instances, and the T*ObjArray. The service should not allocate any parameter instance.

Q4.Q5. For the domain services, you are IMHO allowed to "leak" your domain objects, since those domain services are how the domain objects are allowed.
Perhaps DTO are not needed at this level.
The application layer, which uses the domain services, should define the DTOs, to "uncouple" the domain objects and services.

If your domain service method is about storing the aggregates, and adding some rules, you could have a first minimal implementation, using ORM*() methods to publish a CQRS compatible interface.

In pure DDD, there is no such things as DAOs: this is an implementation detail, which do exist (e.g. if you use the ORM*() mapping methods, and a TSQLRecord for actual storage), but you should not worry about them.

Offline

Board footer

Powered by FluxBB