APIs RESTful com Delphi e DataSnap – Parte II

APIS RESTful com Delphi e DataSnap - DevSpace
APIS RESTful com Delphi e DataSnap

Última atualização em 4 de setembro de 2023 por Willian Tuttoilmondo

Recapitulando

Como vimos na parte I deste artigo, o processo para criação de APIs RESTful com Delphi e DataSnap é um processo simples, mas extenso. Como já iniciamos o projeto, definimos quais eram os detalhes da estrutura, incluindo a estrutura de diretórios. Sendo assim, seguiremos com as implementações que serão utilizadas em nossa API. Como já disse antes, a base para essa implementação é um artigo já escrito anteriormente, onde utilizamos padrões de projeto. Aqui faremos o mesmo, mas teremos uma pequena diferença entre a implementação daquele artigo e essa nova implementação.

Ao longo do artigo veremos a diferença e entenderemos o porquê dela. Mas, como o tempo urge e a Sapucaí é grande, vamos logo ao que interessa.

APIs RESTful com Delphi e DataSnap – Implementações

Para começarmos nossa implementação, vamos lembrar da classe TOperação que vimos no outro artigo. Nela havíamos estabelecido as bases para as demais classes que seriam utilizadas no projeto. Sendo assim, seu conteúdo pode ser visto abaixo:

Ao contrário da versão anterior, esta classe possui apenas um método público além de seu construtor: Efetuar. Além disso, esse método, que anteriormente possuía um retorno do tipo Integer, agora possui o retorno Extended, já que todas as operações da API retornarão um valor Extended. Com isso, as classes TSomaTSubtracaoTMultiplicacaoTDivisao também terão apenas o método Efetuar como público e retornando uma valor Extended, como pode ser visto abaixo:

E, como não poderia faltar, temos o Singleton da nossa Abstract Factory, a qual fará a instância do objeto da operação selecionada para que possamos efetuar nossa operação matemática. Esse código, em relação ao anterior, não sofreu alterações, mas é importante colocá-lo aqui, como visto abaixo:

Com esta etapa da implementação fechada, podemos partir para as implementações que estabelecerão a comunicação com nossa API. É sempre bom lembrar que, para que tudo isso funcione, é necessária uma versão Enterprise ou Archtect do Delphi, a qual pode ser obtida aqui para um teste de 30 dias. Até o momento do fechamento desta série de artigos, a versão disponibilizada era a 11 (Alexandria). Quem quiser testar esse nosso projeto nesta versão e nos contar os resultados, ficaremos muito felizes em ouvir.

Sendo assim, vamos para a próxima etapa.

APIs RESTful com Delphi e DataSnap – Preparando a API

Como já implementamos nossas classes que serão consumidas através da API, chegou a hora de implementar a API em si. o Primeiro passo é remover tudo aquilo que não precisaremos no nosso WebModule. Depois de uma faxina básica, seu código ficou desta maneira:

Como parte da especificação RESTful, alguns aspectos da normalização das rotas são necessários quando planejamos a distribuição de nossa API. Um deles é o nome do “concentrador” ou “serviço” que, no nosso caso, é dscalculator. Além dele, outro aspecto é a versão da API, a qual deve constar na rota de acesso. Como estamos trabalhando com nossa primeira versão, esta será a v1. E para indicarmos que estamos acessando uma API, vamos colocar o termo api no início da rota. Sendo assim, nossa rota completa fica estabelecida como /api/dscalculator/v1/[classe], onde [classe] indica qual classe acessaremos. Quando montarmos nosso ambiente de testes falaremos mais sobre as rotas e o porquê dessa especificação mas, por enquanto, nos atenhamos a isso.

Para iniciar nossa implementação, vamos alterar mais um pouco nossa unit do WebModule. A princípio, mudaremos a seção uses da interface, removendo a unit System.SysUtils de lá é levando-a para a seção uses da implementação. Além disso, vamos adicionar mais algumas units a esta seção, o que vai nos permitir trabalhar com mais liberdade em alguns aspectos, deixando esta seção como vemos abaixo:

E com isso, podemos implementar a primeira verificação de nosso método WebModule1DefaultHandlerAction.

Nesse ponto, começamos a avaliar nossa requisição, a qual vem através do parâmetro Request. A primeira coisa que precisamos checar é se a rota solicitada é válida. Quando chamamos a rota https://localhost/api/dscalculator/v1/soma?a=20&b=30 para acesso à API, parte dessa rota vem através da propriedade InternaPathInfo do parâmetro Request. Sendo assim, e para poder manipulá-lo posteriormente, vamos atribuí-lo à variável local strPathInfo.

Feito isso, precisamos excluir o primeiro caractere / que consta na variável. Isso facilitará nosso processo de quebra da rota em um array de strings, o qual será usado para validar essa mesma rota. A partir daí, dividimos a string em um array de strings utilizado um record helper, sobre o qual já discutimos aqui, e devemos atribuir ao cabeçalho Content-Type da resposta o valor application/json, já que todas as respostas serão um objeto JSON. Depois, verificamos se a quantidade de termos nele é diferente de três, uma vez que a propriedade InternalPathInfo retorna o valor /dscalculator/v1/soma.

Caso nossa verificação confirme que a rota não contém três termos, criaremos um objeto JSON para ser usado como resposta, adicionando a ele um nó booleano indicando falha (“sucesso”: false)  uma mensagem explicativa e amigável do erro. Para completar a resposta, devemos atribuir à ela o StatusCode 400, indicando que a requisição é inválida. Ao corpo da resposta atribuímos o conteúdo do objeto JSON e, assim como liberamos o objeto JSON da memória, efetuamos a saída do método.

Em seguida, implementamos a verificação da versão da API e a existência da classe registrada em nossa factory. Algumas refatorações foram feitas de forma a deixar o código mais limpo, então o método completo pode ser visto abaixo:

Agora, vamos implementar o consumo das classes que já codificamos anteriormente. Isso será acessado através da factory, o que nos garante uma versatilidade maior na hora de fazer implementações mais extensas em nosso projeto. E como precisamos verificar o método de requisição (inicialmente utilizaremos o método GET), faremos essa verificação no momento de invocar o método Efetuar do objeto selecionado.

Nessa implementação, é possível notar que desenvolvemos três métodos restritos ao método WebModule1DefaultHandlerActionSetErrorResponse, que tem a função de formatar respostas de erro da API, GetQueryField, que lê o campo solicitado em uma Query String em uma requisição GET, e DoOperation, que, como o nome já propõe, efetua a operação em si. Com isso, nosso código final ficaria desta forma, tanto para o projeto quanto para o WebModule:

Compilando…

Após toda a implementação, basta compilar o projeto para poder utilizá-lo em um ambiente de testes. O módulo, quando compilado na opção Debug para a plataforma Windows 64-bit, poderá ser localizado no diretório C:\Projetos\Delphi\Datasnap\DSCalculator\bin\Win64\Debug, se mantidas as orientações dadas ao longo do artigo anterior. Mas, fica aqui minha dica: já façam a compilação em modo Release. Nesta técnica de desenvolvimento não há como efetuar o debug do módulo Apache. Caso haja a necessidade de debug, podemos utilizar duas técnicas: pontos de debug que geram um arquivo de log para analisarmos a aplicação e seu comportamento ou construir uma outra aplicação que possamos debugar nossas classes, uma vez que não será necessário debugar o módulo em si.

Em uma oportunidade futura podemos discutir sobre essas técnicas mas, por ora, basta saber que não é possível debugar um módulo Apache.

Tudo compilado. E agora?

Agora que já compilamos nosso módulo Apache, precisamos montar nosso ambiente de testes. Como esse processo é extenso, vamos deixá-lo para a próxima parte do nosso artigo. De qualquer forma, até o momento, já pudemos perceber o quão simples é montar APIs RESTful com Delphi e DataSnap. Nesta técnica conseguimos contornar, inclusive, uma questão técnica do próprio DataSnap, que não nos permitia a utilização de Query Strings para a execução de métodos GET, assim como estabelecia rotas que levam em consideração o nome das classes de métodos utilizadas para o desenvolvimento.

Ah, um arquivo .zip contendo os Class Helpers utilizados no artigo pode ser encontrado aqui.

Então, por ora, ficamos por aqui. Logo mais a parte III do nosso artigo estará no ar. Até mais!

Sobre Willian Tuttoilmondo 12 Artigos
Arquiteto de software com mais de 25 anos de experiência em desenvolvimento de software, especialista em desenvolvimento multicamadas utilizando Embarcadero Delphi e NodeJS para o back-end e o próprio Delphi para o front-end. Usuário Linux desde 1998, é evangelista PostgreSQL, banco de dados no qual é especialista. Ocupa hoje a posição de arquiteto de software na TOTVS, a maior empresa de tecnologia do Brasil, além de ser sócio fundador da LT Digital Labs, empresa especializada em desenvolvimento e treinamentos.

1 Trackback / Pingback

  1. Construindo APIs RESTful nível 3 com Delphi e Datasnap

Faça um comentário

Seu e-mail não será publicado.


*