Acredito que a maior dificuldade de qualquer programador Delphi ao se desenvolver servidores de aplicação utilizando o DataSnap com RESTFul é:
Como mapear os verbos HTTP?
A razão dessa pergunta tem muito a ver com a quantidade de dúvidas que giram em torno do CRUD, Create, Read, Update e Delete, ou seja, a quatro operações básicas de qualquer cadastro em um sistema de informática, em um software.
DataSnap RESTFul – mapeamento dos verbos HTTP
Desde as primeiras versões do DataSnap fatores como dificuldade de entendimento da arquitetura e curva de aprendizado alta afastaram programadores, mesmos os mais experientes, de se aprofundar no DS. Eu confesso que trabalhar com Type Library não era uma tarefa fácil e sempre que precisava desenvolver novos métodos em meus sistemas, rezava a noite inteira para que no dia seguinte acordasse inspirado ou o cliente desistisse da implementação. Aquele negócio era um tormento, difícil de entender, difícil de implementar novos métodos, difícil de debugar. Enfim.
Os tempos passaram e o DataSnap foi ficando mais simples de se trabalhar. Desenvolver software multi-camadas com dbExpress e midas era moleza, ainda que muitos não concordem comigo nesse artigo, mas sim…era fácil demais. Nunca entendi ao certo porque tantos desenvolvedores me enviavam mensagens por email, no blog e em tantos lugares onde escrevia meus artigos. De verdade, as versões mais novas sempre achei muito fácil o mecanismo e a arquitetura de acesso.
Com as verões mais recentes do Delphi veio o Reflection, uma classe (várias classes) para uso do DataSnap juntamente com o FireDAC. Puts, ainda mais fácil. Vejamos.
Você cria o servidor DataSnap, insere um conjunto de componentes do FireDAC para acesso ao seu banco de dados e então desenvolve os métodos de carga dos dados em um ou mais ServerMethods. Depois na aplicação cliente basta usar o assistente do próprio Delphi, criar um DataModule e nele o Delphi cria sozinho uma instância do componente DSRESTConnection + um arquivo de mapeamento dos métodos que eu sempre chamei de PROXY.
Pronto, através do proxy você consegue chamar os métodos no servidor, com parâmetro e tudo.
DMMetodos.Server_MethodClient.METODO_NO_SERVIDOR(Param1..Param10);
Sim, simples assim. Leia como Server_Method o ServerMethods no lado do servidor onde o método existe. Metodo_no_Servidor é a function ou procedure que contém a regra de negócio que precisa ser chamada, executada. Se for uma listagem de produtos por exemplo, ficaria algo como:
//lado servidor function ListarProdutos: TJSONDatasets; Result := //comando para listar //lado cliente var Dados: TJSONDataSets; begin Dados := DMMetodos.ServerMethodsClient.ListarProdutos; ...
Claro que temo mais alguns detalhes, mas basicamente é isso. Criar o método no servidor e chamar do lado cliente. Nesse caso temos um RPC, Remote Procedure Call, uma procedimento de chamada remota. Isso funciona, e te garanto, muito bem.
Mas utilizando essa técnica não temos um RESTFul, ou seja, o modo como o servidor expõe os dados pode ser consumido apenas por uma aplicação também desenvolvida em Delphi ou C++, que são ferramentas da Embarcadero. Salvo algumas ressalvas, isso é o que precisa saber.
Meu servidor precisa ser mais que isso
Beleza, entretanto o servidor precisa ser mais que isso. Preciso consumir os dados do servidor através de outras tecnologias. Quero criar minha própria API, tenho clientes que precisam desenvolver verticais de seus sistema em PHP, C#, relatórios em outras ferramentas, linguagens. Tenho parceiros que consomem partes do meu sistema que não podem ser totalmente expostas, e agora?
Agora vem a notícia boa. Posso desenvolver um servidor de aplicações totalmente RESTFul, que pode expor meus métodos utilizando padrões de mercado, como JSON. Perfeito, JSON. Essa é a grande vantagem. Usar notações JSON faz com que meu servidor de aplicações possa ser consumido de diferentes formas. Posso criar uma API completa capaz de exportar e receber dados de diferentes linguagens e IDEs…
Escalabilidade? Por que não?
Sim, posso ter “n” servidores DataSnap rodando simultaneamente atendendo a milhares de conexões, requisições, downloads e uploads de fotos, arquivos de forma geral. Mas isso é conversa para outro momento ou se preferir, assista o vídeo Como ESCALAR servidores DataSnap em 1o minutos? presente no meu YouTube.
A questão aqui é mais básica um pouco.
Como criar um CRUD no DataSnap RESTFul?
A primeira coisa que precisa saber é “como fazer o mapeamento dos verbos HTTP?”. Sim. Se vai trabalhar com internet, com HTTP, precisa entender o básico. E esse básico tem a ver com os verbos. São 04 ao todo.
GET
POST
PUT
DELETE
Acredito que já os conheça, mas vamos lá.
GET – é o verbo responsável por leitura, listagem, por adquirir os dados. Traduzindo: SELECT no banco.
POST – verbo responsável por gravar novos dados. Traduzindo: INSERT INTO
PUT – esse é usado para gravar dados alterados. Traduzindo: UPDATE TABELA
DELETE – esse é fácil, exclui dados no servidor. Traduzindo: DELETE FROM TABELA
Então, quando precisamos fazer as quatro operações básicas de um cadastro utilizando RESTFul, precisamos entender esses quatro verbos. Muito bem, e agora no Delphi, como funciona?
Vamos lá. No DataSnap RESTFul há uma forma extremamente simples de fazer o mapeamento. Basta criamos quatro functions/procedures no nosso ServerMethod. Olha só:
function NomeDaColecao: TJSONArray;
function AcceptNomeDaColecao: TJSONArray;
function UpdateNomeDaColecao: TJSONArray;
function CancelNomeDaColecao(AID: Integer): TJSONArray;
Onde NomeDaColecao é geralmente o nome do recurso que deseja listar, a tabela no banco. Exemplo:
function Clientes: TJSONArray; function AcceptClientes(AIDCliente: integer): TJSONArray; function UpdateClientes: TJSONArray; function CancelClientes(AID: Integer): TJSONArray;
Perceba que temos o recurso Clientes, nossa tabela de clientes onde faremos as nossas operações, e a frente dos métodos há palavras, exceto no primeiro método. Eu retorno sempre um TJSONArray, já que devolvo para a aplicação cliente sempre algum resultado, nunca vazio, mesmo que o resultado seja só uma frase “Dados não encontrados!” ou “Tabela vazia!”.
As palavras à frente dos verbos são:
Accept = Nosso VERBO PUT;
Update = Nosso VERBO POST;
Cancel = Nosso VERBO DELETE;
O primeiro deles não possui uma palavra, e será mapeado para GET, nosso SELECT. Fácil. Só tem um detalhe. No DataSnap RESTFul, os verbos Accept (Put) e Update (Post) estão invertidos em relação ao padrão de mercado. Sim, há uma inversão.
O PUT nesse caso torna-se o verbo que vamos mapear como nosso UPDATE TABELA e o verbo POST faremos o mapeamento para INSERT INTO. Por isso, novamente incluindo um exemplo, veja:
type {$MethodInfo ON} TMain = class(TDataModule) private { Private declarations } public { Public declarations } function Pedidos: TJSONArray; //Get = Select function AcceptPedidos(const AID_Usuario, AID_Pedido_Mobile: integer): TJSONArray; //Put = Update function UpdatePedidos: TJSONArray; //Post = Insert function CancelPedidos(const AID: Integer): TJSONArray; //Delete = Delete end;
Acima fica mais claro. Em um servidor DataSnap RESTFul onde eu queria fazer o mapeamento dos verbos HTTP Get, Put, Post e Delete, basta seguir a regra acima. Toda coleção deve ter os quatro verbos. Desse modo, quando as requisições chegarem no servidor, o DS vai automaticamente procurar o verbo correspondente.
A requisição será usada da seguinte forma:
http://IP:Porta/datasnap/rest/NOME_DO_SERVER_METHOD/COLECAO/PARAMETROS (SER HOUVER)
Exemplo:
//Get – Listando a tabela de pedidos
http://200.323.12.50:8080/datasnap/rest/ServerMethodsGerais/Pedidos
//Put – Altercando dados da tabela de pedidos
http://200.323.12.50:8080/datasnap/rest/ServerMethodsGerais/Pedidos
//Post – Inserindo dados da tabela de pedidos
http://200.323.12.50:8080/datasnap/rest/ServerMethodsGerais/Pedidos/id/123456
//Put – Excluindo dados da tabela de pedidos
http://200.323.12.50:8080/datasnap/rest/ServerMethodsGerais/Pedidos/id/123456
Hummm, estranho. Todos os urls apontam para o mesmo url. Sim, é assim mesmo. O que vai diferenciar é o header da requisição que será alterado para Get, Put, Post ou Delete. Em Delphi isso é feito modificando uma propriedade no componente RESTClient ou enviando essa informação na formação da requisição.
Bem, para não se estender muito no artigo, você pode assistir minha vídeo-aula sobre o assunto no meu YouTube. O nome do vídeo é “Mapeamento dos VERBOS HTTP no DataSnap RESTFul” ou ainda assistir meu WorkShop “DataSnap RESTFul que será ministrado no dia 24 de Agosto, próximo sábado a partir das 11h no horário de Brasília.
Basta acessar o canal do YouTube as 11h e conferir o conteúdo.
Aproveite e conheça noss Passaporte TDevRocks, uma assinatura anual com acesso a TODOS os nossos workshops, reprises e códigos-fonte do mais variados assuntos.
Clique no banner abaixo para saber mais.