You are on page 1of 11

MANUAL SERVIDOR DATASNAP JSON

UM NOVO PADRÃO DE INTERCÂMBIO


Com a evolução de aplicações em três camadas, cada vez mais se tem a necessidade de
transferir dados entre aplicações, principalmente com a evolução rápida dos dispositivos
móveis que trouxe uma complexidade a mais, devido a sua diversificação de plataform as e
linguagens que as mesmas utilizam. Hoje quem não se adequar a essa realidade, fica
ultrapassado no mercado. Existem duas formas principais para o intercâmbio entre aplicações
uma é o XML e outra é o JSON.

Quando uma empresa precisa mover parte de seu sistema local para a WEB sempre existe a
dúvida da compatibilidade com outros sistemas e dispositivos. O REST praticamente encerra
com essa preocupação, pois não utiliza recursos específicos desta ou aquela linguagem ou
ambiente, ele utiliza os padrões WEB de comunicação. Dessa forma tem-se a certeza da
acessibilidade de informações.

Ao comparar a quantidade de texto fica claro o porquê da popularidade do padrão JSON entre
os serviços REST. Menos texto é igual a menor tamanho que é igual a menos tempo de
tráfego.

CRIANDO O PROJETO
CONFIGURAÇÕES INICIAIS DO SERVER

1. Abra o menu File > new > Other > DataSnap

2. Selecione REST Application

3. Selecione Stand-Alone-Application e clique em next.

4. Selecione VCLApplication e clique em next.


5. Selecione a porta, teste e clique em next.

6. Configure conforme mostra abaixo e depois clique em next.

7. Selecione TComponent e clique em next.


8. Selecione a pasta onde queira salvar o projeto e depois clique em finish.

9. Salve todos módulos em pastas específicas de sua escolha. Neste manual, preferi não mudar
os nomes que o próprio Delphi da às units. Assim, serão criadas as units ServerContainerUnit1,
ServerMethodsUnits1, WebModuleUnit1 e algumas pastas que serão necessárias para o JSON.

CONSULTANDO DADOS
CRIANDO O DATAMODULE DO SERVIDOR E INSERINDO UMA QUERY DE BUSCA
1. Neste projeto que servirá como servidor, adicione um DataModule com uma Query para
consultar uma tabela ne um determinado banco de dados. Para o nosso exemplo, utilizaremos
o Firebird com um Banco de Dados que possui uma tabela chamada “CADPRODUTOS”.

2. Criaremos então uma Query chamada FDQProdutos que se conecta a um banco de dados para
fazer uma busca nesta tabela específica. Abaixo está o comando para a busca que passaremos
ao componente FDQProdutos:
select * from cadproduto where
cadproduto.id_produto
=:id

3. Adicione os componentes FDStanStorageJSONLink1 e FDStanStorageBinLink1 ao DataModule.

4. Salve o DataModule numa pasta específica.

MÉTODOS NO SERVER METHODS

Como estamos utilizando do DataSnap Rest, duas units são criadas: uma é a Server Container e outra
é a Server Methods. Criaremos os procedimentos dentro do ServerMethods na área pública da classe
TServerMethods. Siga os passos abaixo para a criar a rotina de consulta no banco de dados:
1. Crie uma função na área pública da classe TServerMethods do ServerModule que servirá para
fazer a consulta da Query FDQProdutos no DM do Servidor. Esta função recebe um valor
inteiro como parâmetro (um id da tabela no BD) e retorna um TFDJSONDataSets. No nosso
exemplo chamaremos a função de BuscaProduto.

function BuscaProduto(id: Integer): TFDJSONDataSets;

2. A princípio o Delphi não vai aceitar o retorno. Para isso basta adicionar as duas units
System.JSON e Data.FireDACJSONReflect.

Uses System.JSON, Data.FireDACJSONReflect;

3. Implemente a função com Ctrl +Shit + C e passe:

DM.FDQProdutos.Active := False;
DM.FDQProdutos.Params[0].AsInteger := id_cliente;
DM.FDQProdutos.Active := True;

Os nomes aqui são da sua escolha, bem como as tabelas. Só estamos fazendo um exemplo de
consulta de dados por parâmetros, assumindo que você já conhece o processo.

4. Logo abaixo deste primeiro bloco, informaremos o result desta função, que será do tipo
TFDJSONDataSets. Este Result recebe a criação da classe TFDJSONDataSets.

Result := TFDJSONDataSets.Create;

5. Após feita a criação da classe TFDJSON podemos passar a escrever o conjunto de Dados na
forma JSON com o comando Writer:

TFDJSONDataSetsWriter.ListAdd(Result,DM.FDQProdutos);

Os dois parâmetros são primeiramente onde será escrito os dados em forma JSON e segundo
qual a fonte do conjunto de dados. A razão de usarmos o Writer é que estamos buscando
dados de uma Query e escrevendo em um JSONDataSet. Mais tarde, utilizaremos este
JSONDataSet para alimentar uma Tabela que será mostrada para o cliente.

6. Se quiséssemos adicionar mais consultas devemos repetir os passos 1,3 e 5.

7. Por fim, vamos ativar a Query FDQProdutos de novo.

DM.FDQProdutos.Active := True;

8. Feito isso podemos colocar o servidor para rodar e começar a fazer a aplicação cliente.

CRIANDO O DATA SNAP REST CLIENT MODULE PARA FAZER UMA CONSULTA

Antes de começarmos a fazer as rotinas para a consulta, vamos preparar o


ambiente para gerarmos as funções provindas do server.

1. Crie um novo projeto VCLForms Application e adicione-o com o


projeto do server. Se quiser faça um grupo de projeto. Nomeio-o
de forma a defini-lo como o projeto cliente.
2. Insira um Edit , um Button, um Dbgrid, um DataSource e um Memtable (chamaremos o
MemTable do cliente de TableProdutos).

3. Adicione os componentes FDStanStorageJSONLink1 e FDStanStorageBinLink1 ao DataModule


que adicionamos no item 3 da sessão CRIANDO O DATAMODULE DO SERVIDOR E INSERINDO UMA
QUERY DE BUSCA

4. Agora entre no menu File > New > Other > DataSnap > DataSnap REST Client Module.

5. Selecione Remote e clique em next.

6. Selecione DataSnap Stand Alone server em depois clique em next.

7. Passe o host 127.0.0.1 e a mesma porta que você utilizar no servidor.


8. Clique em finish e salve o ClientModule e a ClientClass.

Veja que surgiram duas novas units. Uma é a


ClientModuleUnit1, que se conecta ao servidor via
TCP/IP e captura todos os métodos do servidor. Outra
é a ClientClassUnit que implementa as funções capturadas pelo
ClientModule. Para gerarmos as funções do servidor no cliente devemos ir
no ícone de conexão do ClientModule e clicar em Generate DataSnap Client
Classes.

CRIANDO A FUNÇÃO DE CONSULTA NO CLIENTE

1. Configure a DBGrid com o DataSource, e o DataSource com o MemTable, nas propriedades


Dataset.

2. Faça um recorte-cole dos campos que você adicionou da Query FDQProdutos do servidor e
cole no Memtable do cliente.

Server para
Client

3. Agora vá na unit ClientModule e no componente de conexão clique em Generate DataSnap


Client Classes. Importante estar configurado com o mesmo IP e porta do servidor, senão pode
dar erro ou pegar os métodos de outro servidor. (Vide o item 7 da sessão CRIANDO O DATA SNAP
REST CLIENT MODULE PARA FAZER UMA CONSULTA)

4. Criaremos agora a rotina para pesquisar os dados que está na tabela do servidor. Precisaremos
de uma variável do tipo TFDJSONDataSets que servirá para guardar as informações da busca.
Ela ficará no próprio evento do clique do botão. Esta variável receberá o procedimento que
está na classe ServerMethods da unit ClientClass. No projeto client, ao clicar no botão passe:

Var Dados: TFDJSONDataSets

Dados representa a variável neste caso. Se o Delphi não reconhecer, é por que faltam as units
System.JSON e Data.FireDACJSONReflect.

Dados:=ClientModule1.ServerMethods1Client.RetornaCidade(StrToInt(edtBusca.Text));

Assert(TFDJSONDataSetsReader.GetListCount(Dados)=1);
A função Assert serve apenas como uma verificação para contar quantos itens há lista de dados
do JSON. Estamos igualando a um pois somente inserimos um pacote (ou lista), ou seja,
estamos passando apenas uma consulta.

5. Por fim, passaremos os dados do JSON para o MemTable.

TableProdutos.Active := False;
TableProdutos.AppendData(TFDJSONDataSetsReader.GetListValue(Dados,0));
TableProdutos.Active := True;

GRAVANDO DADOS
CRIANDO A FUNÇÃO GRAVAR NO SERVER

Criaremos agora a rotina para gravar um registro com o REST DataSnap. A lógica segue a mesma:
Primeiro criamos uma Query para executar o comando update. Criamos então uma função no Server
Methods passando como parâmetros os valores desejados e executamos o SQL da Query. Por fim
chamamos a função no botão do cliente. Antes de começar a criar a função do servidor, feche-o se
estiver rodando.

1. No DataModule do servidor, adicione uma Query para atualizar o registro que deseja e passe
o comando update. Chamaremos esta Query de GravarProdutos.

update
cadproduto
set
cadproduto.preco = :preco,
cadproduto.custo = :custo
where
cadproduto.id_produto =:id_produto

2. Crie também um Memtable no servidor e chame-o de TabelaProdutos. Copie e cole os campos


da Query de FDQProduto para este MemTable. (Veja item 2 da sessão CRIANDO A FUNÇÃO DE
CONSULTA NO CLIENTE );

3. No Server Methods, crie uma função chamada GravarProduto na área pública da classe
TServerMethods. Esta função receberá um conjunto de dados do tipo TJSONDataSets e
retornará um Boolean.

function GravarCliente(ds_cliente:TFDJSONDataSets):Boolean;

4. Feita a implementação desta função passe:

DataModule1.TabelaProdutos.Active := False;

DataModule1.TabelaProdutos.AppendData(TFDJSONDataSetsReader.GetListValue(ds_Produtos,0));

DataModule1.GravarProduto.ParamByName('CUSTO').AsCurrency :=
DataModule1.TabelaProdutosCUSTO.AsCurrency;

DataModule1.GravarProduto.ParamByName('PRECO').AsCurrency :=
DataModule1.TabelaProdutosPRECO.AsCurrency;

DataModule1.GravarProduto.ParamByName('ID_PRODUTO').AsInteger :=
DataModule1.TabelaProdutosID_PRODUTO.AsInteger;
try
DataModule1.GravarProduto.ExecSQL;
Result := True;
Except
Result := False;
end;

Atenção! Perceba que estamos passando parâmetros em formato Currency. Se este é o caso,
devemos informar nas propriedades de cada campo do MemTable TabelaProduto a opção
currency marcada!

5. Abra e inicie o servidor agora que você concluiu a função.

CHAMANDO A FUNÇÃO GRAVAR NO CLIENT

Agora chamaremos esta função no lado do cliente. É importante o servidor estar rodando e que o
componente de conexão do ClientModule esteja configurado com a mesma porta e ip do serviço.

1. Repita o passo 3 da sessão CRIANDO A FUNÇÃO DE CONSULTA NO CLIENTE.

2. No form de consulta crie um botão para chamar a função GravarProduto do ServerMethods


no ClientModule. Lembrando que esta função requer um conjunto de dados TFDJSONDatasets,
o que tornará necessário criarmos uma variável deste tipo que recebe a criação do desta
classe. Portanto feita esta variável no dentro do procedimento do clique do botão passe:

ds_Produtos := TFDJSONDataSets.Create;

No nosso caso, chamamos a variável de ds_Produtos.

3. Agora passaremos o comando para escrever os dados na forma JSON em um conjunto de


dados buscando de um DataSet.

TFDJSONDataSetsWriter.ListAdd(ds_Produtos,DataModule2.TableProdutos);

Perceba que utilizamos a função Writer e adicionamos um item na lista. O primeiro parâmetro
é onde o será escrito e o segundo qual a fonte de dados a ser escrita.

4. Agora chamaremos a função GravarProdutos do ClientModule que receberá como parâmetro


o conjunto de dado JSON ds_Produtos que criamos, no nosso caso, a variável que por sua vez
já está populada de dados na forma JSON.

ClientModule1.ServerMethods1Client.GravarProdutos(ds_Produtos,'');

Rode o cliente, faça uma busca, altere no dbgrid, grave e faça uma busca novamente deste
produto. Veja as alterações.
EXCLUINDO DADOS
CRIANDO A FUNÇÃO EXCLUIR NO SERVER
Criaremos agora a rotina para a exclusão de dados via REST DataSnap. Faremos o mesmo processo que
fizemos anteriormente criando uma Query para o comando de exclusão. Depois criamos a função no
servidor passando um parâmetro desejado e retornando um valor booleano. Após a criação da função
no Servidor passamos a chamá-la no Cliente.

1. No DataModule do Servidor, adicione uma Query e passe o comando SQL de exclusão. Para o
nosso exemplo chamaremos esta Query de ExcluiProduto.
delete from
cadproduto
where
cadproduto.id_produto = :id_produto

2. Crie agora na área pública da classe ServerMethods no uma função chamada ExcluiProduto.
Esta função receberá um valor inteiro e retornará um valor booleano. Como é óbvio, o valor
inteiro se destina para excluir o item da tabela.

function ExcluiProduto(id_produtos:Integer):Boolean;

3. Após feita a implementação, simplesmente passe:

try
DataModule1.ExcluiProduto.Active := False;
DataModule1.ExcluiProduto.ParamByName('ID_PRODUTO').AsInteger := id_produtos;
DataModule1.ExcluiProduto.ExecSQL;
Result := True;
except
Result := False;
end;

4. Feitas as alterações, agora podemos colocar o servidor para rodar e começar a programar o
cliente para chamar esta função.

CHAMANDO A FUNÇÃO EXCLUIR NO CLIENT


1. Repita o passo 3 da sessão CRIANDO A FUNÇÃO DE CONSULTA NO CLIENTE.

2. Crie um botão para excluir e após isso passe:

ClientModule1.ServerMethods1Client.ExcluiProduto(DataModule2.TableProdutosID_PRODUTO.As
Integer);

O processo é bem simples.

INSERINDO DADOS
CRIANDO A FUNÇÃO INSERIR NO SERVER
Para finalizar este caso de estudo simples, vamos completar criando o procedimento inserir.
Seguiremos basicamente a mesma lógica dos procedimentos anteriores. Primeiro criamos a Quey para
o comando de inserção no DataModule do server. Depois criamos a função no ServerMethods. Criada
a função podemos ligar o servidor e gerar a função no ClientModule. Após isso basta criar um botão
no view do cliente e chamar a função do server.

1. Crie uma Query no DataModule do servidor chamada Inserir. Para o nosso exemplo
passaremos este comando:
insert into
cadproduto
values
(
:Id,
:Desc,
:grupo,
:custo,
:preco,
:cod,
:un
)

2. Agora, no ServerMethods criaremos a função na área pública da classe InserirProduto, que


receberá um TFDJSONDataSets e retornará um boolean.

function InserirProduto(ds_Produtos:TFDJSONDataSets):Boolean;

3. Feita a implementação, desativaremos o MemTable do DataModule do servidor:

DataModule1.TabelaProdutos.Active := false;

4. Agora utilizaremos o AppendData nesta tabela pegando os dados do parâmetro ds_produtos:

DataModule1.TabelaProdutos.AppendData(TFDJSONDataSetsReader.GetListValue(ds_Produtos,0)
);

Como estamos recebendo informações, utilizaremos os comando Reader do JSON.

5. Seguindo na sequência, falta passar os parâmetros à Query InserirProduto já carregados ao


MemTable:

DataModule1. InserirProduto.ParamByName('ID').AsInteger :=
DataModule1.TabelaProdutosID_PRODUTO.AsInteger;0

DataModule1. InserirProduto.ParamByName('DESC').AsString :=
DataModule1.TabelaProdutosDESCRICAO.AsString;

DataModule1. InserirProduto.ParamByName('GRUPO').AsString :=
DataModule1.TabelaProdutosGRUPO.AsString;

DataModule1. InserirProduto.ParamByName('CUSTO').AsFloat :=
DataModule1.TabelaProdutosCUSTO.AsFloat;

DataModule1. InserirProduto.ParamByName('PRECO').AsFloat :=
DataModule1.TabelaProdutosPRECO.AsFloat;

DataModule1. InserirProduto.ParamByName('COD').AsString :=
DataModule1.TabelaProdutosCODIGO.AsString;

DataModule1. InserirProduto.ParamByName('UN').AsString :=
DataModule1.TabelaProdutosUN.AsString;
6. Por fim utilizaremos try except para executar o comando SQL juntamente informando qual
será o Result:

try
DataModule1.InserirProduto.ExecSQL;
Result := True;
except
Result := False;
end;

7. Finalizamos a rotina no servidor. Agora coloque-o para rodar e vamos começar a programar a
rotina no cliente.

CHAMANDO A FUNÇÃO INSERIR NO CLIENT


1. Repita o passo 3 da sessão CRIANDO A FUNÇÃO DE CONSULTA NO CLIENTE.

2. Crie um botão para inserir um novo registro no view do Cliente.

3. Na implementação, crie uma variável local do tipo TFDJSONDataSets, e passe a criação desta
classe para ela:

ds_Produtos := TFDJSONDataSets.Create;

4. Após a criação da classe nesta variável, utilizaremos o comando Write do JSON para incluir um
item na lista do conjunto de dados.

TFDJSONDataSetsWriter.ListAdd(ds_Produtos, DataModule2.TableProdutosID

O que acabamos de fazer foi preparar JSON para então assim receber o comando.

5. Se você fez o comando do item 1 agora é só chamar a função do ClientModule.

ClientModule1.ServerMethods1Client. InserirProduto (ds_cliente,'');

You might also like