Escolar Documentos
Profissional Documentos
Cultura Documentos
HasAuthentication
UserName
Password
Esta classe é instanciada no Form Main e alimentado essas propriedades, onde HasAuthentication do tipo boolean informa se terá ou não
autenticação. UserName e Password deverão ser informados caso HasAuthentication = True.
A IDE faz a ligação automática dele aos componentes RestClient que existirem no form.
Basta rodar que sua aplicação Client já estará fornecendo dados de autenticação para o servidor.
Interessante observar o comportamento de um client do tipo Navegador, ao chamar a URL por ele, recebemos um diálogo informando que
necessita de autenticação. Ao fornecer os dados corretos a URL é chamada novamente com os dados digitados.
Twitter
Facebook
Google
3 Comentários
Este artigo é uma continuação do anterior, Se você não leu, faça agora para entender o contexto desse.
Objetivo
O objetivo deste projeto é implementar WebServices REST+JSON em Delphi na versão PROFESSIONAL a partir do Delphi XE2 e
posteriores :
Definição de Rest
Segundo a WikiPedia :
O termo REST se referia, originalmente, a um conjunto de princípios de arquitetura (descritos mais abaixo), na atualidade se usa no sentido
mais amplo para descrever qualquer interface web simples que utiliza XML e HTTP (ou YAML, JSON, ou texto puro), sem as abstrações
adicionais dos protocolos baseados em padrões de trocas de mensagem como o protocolo de serviços Web SOAP
O Web Service apresentado aqui possui várias características de um REST Web Service são elas :
Cache
A Estrutura do Projeto
O exemplo será um cadastro de alunos (CRUD) bem simples, sem validações, sem checagem de erros, porque o objetivo aqui é somente
mostrar as operações REST.
Foi implementado um “mini-framework” de trabalho, ou seja é necessário encaixar os seus novos métodos nos locais adequados dentro da
estrutura montada.
Observe que temos um form Principal, uma Unit de Tipos (SysTypes), um unit com rotinas de auxílio (ServerUtils) e a principal onde iremos
trabalhar, a ServerMethodsUnit1.pas
Na Unit ServerMethodsUnit1.pas temos a classe TServerMethods1 já com alguns ServerMethods implementados, são eles :
ServerMethod OPERAÇÃO
ConsultaAluno GET
GetListaAlunos GET
AtualizaAluno POST
InsereAluno PUT
ExcluiAluno DELETE
Obs : Para essa simulação, não estamos usando banco de dados, para facilitar o teste e evitar que se instale servidores de banco de dados ou
criar tabelas, usamos arquivo texto e uma stringlist apenas para demonstrar as operações REST.(GET/PUT/POST/DELETE)
Entendendo a estrutura
Para cada operação (GET/PUT/POST/DELETE) temos um método público na classe TServerMethods da unit ServerMethodsUnit1 :
Para inserirmos um novo método em nosso REST webservice precisamos codificar o próprio método, veja abaixo o server method que
retorna a lista de alunos cadastrados :
E depois colocar dentro de CallGETServerMethod, a chamada para ele, seguindo o padrão existente :
O Método CallGetServerMethod será chamado pela engine do framework para toda requisição GET vinda de um client qualquer, desde que
este client especifique que a operação é um GET.
CallPUTServerMethod
CallPOSTServerMethod
CallDELETEServerMethod
São rotinas wrappers onde você encaixa a chamada para o Server Method que você criar.
Pelo padrão adotado, primeiro ele testa Argumentos[0] que deverá chegar aqui com o nome do server method, ele testa também a quantidade
de argumentos passados para um dado Server Method, caso a quantidade de argumentos passados não seja a que ele espera receber, retorna
uma string JSON indicando erro, quem define a quantidade de argumentos é você.
O array Argumentos sempre conterá o nome do método e em seguida os argumentos, portanto exemplificando para um serverMethod que
tenha 2 argumentos, teremos Length(Argumentos) = 3
Se a quantidade de argumentos estiver correta, chame o Server Method passando os parâmetros vindos do Array Argumentos.
o método em si
e a chamada dele em um dos métodos abaixo: CallGetServerMethod, CallPUTServerMethod, CallPOSTServerMethod
ou CallDELETEServerMethod conforme for a operação desejada.
a complexidade acaba aqui, é só isso que precisa fazer, o resto a engine do framework faz pra você.
O framework nada mais é do que o processamento do evento OnGetCommand e OnCommandOther do idHttpServer cuidando de separar
cada operação e argumentos, isso pode ser visto no frmMain da aplicação.
Convenções
Antes de codificar estabelecemos algumas convenções de URL :
Baixe o RestClient
Não há restrições neste framework vindos do Componente idHttpServer visto que o mesmo utiliza os limites da máquina para executar as
threads, então se sua máquina possui só um pouquinho de memória, pode ter certeza pelo menos umas 100 threads simultâneas serão
executadas normalmente.
O que determinará o desempenho será o volume de dados retornado, a complexidade da query e e esforço que o banco faz para executá-la,
quantidade de memória, CPU.
Aqueles que quiserem realizar testes de estabilidade e performance fiquem a vontade para fazer e divulgar resultados.
Testes de concorrência
O componente idHttpServer que foi utilizado aqui, implementa MultiThread, cada requisição vinda de um client qualquer, é criada uma
thread para processamento. Para realização de testes de concorrência, retire o TStringList e a gravação em arquivo texto dos métodos e a
substitua por banco de dados. A utilização desse artifício aqui foi somente para efeito de demonstração da aplicação, arquivos textos não
funcionarão como persistência de dados numa aplicação multi-threaded a não ser que se implemente sincronização das threads o que
também gera atraso na performance.
Tratamento de erros
Num aplicativo servidor não se permite a exibição de mensagens e nem deixar que solte exceções, todas elas devem ser tratadas e guardadas
em log se for o caso, se você permitir o sistema soltar uma exceção por um erro qualquer por exemplo numa query, o webservice vai parar
de responder e precisará ser reestartado.
Então faça sempre uso em todos os ServerMethods de Try/Except seguindo a forma abaixo :
Try
Try
// Instruções do Server Method aqui
Except
ON E:Exception Do
// Adiciona Log em arquivo texto
End
Finally
// Libera objetos se tiver algum
End;
Tipos Retornados
Os tipos retornados são sempre String em JSON padronizando ao máximo o que se espera de um servidor REST.
Os memos criados na tela principal (frmMain) foram usados apenas para teste e demonstração da aplicação, em produção retire a atualização
desses memos ou faça a gravação deles em arquivo a cada mudança de data, limpando o memo logo em seguida, Pois um Memo que nunca
é limpo irá consumir toda a sua memória.
O RestWebService foi feito no XE2, e devido a versão do Indy ser diferente em versões mais novas do Delphi, foi preciso colocar
compilação condicional. Então para as versões XE2, XE7, XE8 e DX Seattle a compilação condicional já foi feita, basta abrir compilar e
rodar.
Para que funcione nas versões XE6, XE5, XE4 e XE3 basta replicar a compilação condicional dessas versões e compilar, veja os pontos onde
foi usada na Unit ServerUtils :
e na Unit ServerMethodsUnit1 :
Conclusão
Penso que o objetivo inicial foi atingido, que era ter um webservice REST + JSON utilizando apenas o Indy e o Delphi professional.
O DataSnap é um produto completo, bem pensado, cheio de recursos e CARO ! é um produto para quem quer ter uma vasta gama de opções
e funcionalidades a seu dispor.
Para aplicações menores em que os recursos existentes no Datasnap não são tão essenciais, uma aplicação servidora como essa pode
resolver e você economizar uma boa grana usando este mini-framework na versão Professional do Delphi pagando apenas 1/3 do valor da
versão Enterprise, a que vem com o DataSnap.
Share this:
Twitter
Facebook
Google
21 Comentários