Delphi – Gerando Unit / Classes de um JSON

Estava trabalhando para simplificar o TRESTClient do DataSnap  e implementar alguns recursos que gostaria de ter e não encontrei no componente distribuido com o delphi ( Package para TRESTSocialClient ). Mapear as respostas Array para um TFDDataset primordial para facilitar o desenvolvimento (ex: TRESTSocialClientDataset). E quando não é possível mapear para um Dataset… código+código+bug+complexo…

Quando trabalho com um Servidor REST Datasnap escrito para delphi – a integração é simples utilizando o “Wizard” para criar um projeto REST Client disponível. Quando o servidor REST responde para múltiplas plataformas é imperativo que o servidor envie respostas “padronizadas” que sejam compatíveis com a plataforma que o cliente utiliza. O caminho mais rápido é responder JSON padrão evitando respostas específicas de uma plataforma ou outra.

Exemplo: um método não pode responder com um TDataset.Data como é o indicado pelo Delphi… isto obrigaria que o cliente seja igualmente um Delphi.. Então para manter padrão o método deve responder com um TJSONValue ou TJSONObject.

Tomando por base o Servidor Datasnap do post “FireDAC – Datasnap” onde publica o método  GetCliente/{cnpj} (http://localhost:8080/datasnap/rest/TServerMethods1/GetCliente/123456) que retorna:

[code lang=”JSON”]
{"result":[{"cliente":[{"RowId":1,"codigo":1,"nome":"Embarcadero SA","cidade":"Sao Paulo","estado":"SP","endereco":"Rua…xxxx…,10","debitos":100000.12},{"RowId":2,"codigo":2,"nome":"Embarcadero SA2","cidade":"Sao Paulo","estado":"SP","endereco":"Rua…xxxx…,10","debitos":100000.12}],"adicional":[{"codigo":1,"nome":"Exemplo 2"}]}]}
[/code]

Nas andanças pelos BLOGs de MVPs encontrei um projeto “Introducing JsonToDelphiClass” que aponta para o repositório com o código do projeto.

O projeto JsonToDelphiClass permite que a representação JSON de retorno do servidor DataSnap seja colado no espaço para texto indicada e usar o botão de geração da Unit contendo a classe Delphi para a representação JSON.

As classes geradas pelo projeto possuem um método que fornecendo o código de retorno do servidor – popula o objeto delphi – facilitando a conversão da estrutura JSON para Classe.

class function FromJsonString(AJsonString: string): T... (criar a classe e popula)

.

Passando aquele retorno do Servidor, veja como ele construiu as classes para a representação JSON:

[code lang=”pascal”]
unit JsonRestServer;

// *************************************************
// Generated By: JsonToDelphiClass – 0.65
// Project link: https://github.com/PKGeorgiev/Delphi-JsonToDelphiClass
// Generated On: 2016-04-10 15:41:06
// *************************************************
// Created By : Petar Georgiev – 2014
// WebSite : http://pgeorgiev.com
// *************************************************

interface

uses Generics.Collections, Rest.Json;

type

TAdicionalClass = class
private
FCodigo: Extended;
FNome: String;
public
property codigo: Extended read FCodigo write FCodigo;
property nome: String read FNome write FNome;
function ToJsonString: string;
class function FromJsonString(AJsonString: string): TAdicionalClass;
end;

TClienteClass = class
private
FRowId: Extended;
FCidade: String;
FCodigo: Extended;
FDebitos: Extended;
FEndereco: String;
FEstado: String;
FNome: String;
public
property RowId: Extended read FRowId write FRowId;
property cidade: String read FCidade write FCidade;
property codigo: Extended read FCodigo write FCodigo;
property debitos: Extended read FDebitos write FDebitos;
property endereco: String read FEndereco write FEndereco;
property estado: String read FEstado write FEstado;
property nome: String read FNome write FNome;
function ToJsonString: string;
class function FromJsonString(AJsonString: string): TClienteClass;
end;

TResultClass = class
private
FAdicional: TArray<TAdicionalClass>;
FCliente: TArray<TClienteClass>;
public
property adicional: TArray<TAdicionalClass> read FAdicional write FAdicional;
property cliente: TArray<TClienteClass> read FCliente write FCliente;
destructor Destroy; override;
function ToJsonString: string;
class function FromJsonString(AJsonString: string): TResultClass;
end;

TRootClass = class
private
FResult: TArray<TResultClass>;
public
property result: TArray<TResultClass> read FResult write FResult;
destructor Destroy; override;
function ToJsonString: string;
class function FromJsonString(AJsonString: string): TRootClass;
end;

implementation

{TAdicionalClass}

function TAdicionalClass.ToJsonString: string;
begin
result := TJson.ObjectToJsonString(self);
end;

class function TAdicionalClass.FromJsonString(AJsonString: string): TAdicionalClass;
begin
result := TJson.JsonToObject<TAdicionalClass>(AJsonString)
end;

{TClienteClass}

function TClienteClass.ToJsonString: string;
begin
result := TJson.ObjectToJsonString(self);
end;

class function TClienteClass.FromJsonString(AJsonString: string): TClienteClass;
begin
result := TJson.JsonToObject<TClienteClass>(AJsonString)
end;

{TResultClass}

destructor TResultClass.Destroy;
var
LclienteItem: TClienteClass;
LadicionalItem: TAdicionalClass;
begin

for LclienteItem in FCliente do
LclienteItem.free;
for LadicionalItem in FAdicional do
LadicionalItem.free;

inherited;
end;

function TResultClass.ToJsonString: string;
begin
result := TJson.ObjectToJsonString(self);
end;

class function TResultClass.FromJsonString(AJsonString: string): TResultClass;
begin
result := TJson.JsonToObject<TResultClass>(AJsonString)
end;

{TRootClass}

destructor TRootClass.Destroy;
var
LresultItem: TResultClass;
begin

for LresultItem in FResult do
LresultItem.free;

inherited;
end;

function TRootClass.ToJsonString: string;
begin
result := TJson.ObjectToJsonString(self);
end;

class function TRootClass.FromJsonString(AJsonString: string): TRootClass;
begin
result := TJson.JsonToObject<TRootClass>(AJsonString)
end;

end.

[/code]

 

 

 

2 comentários

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *