RaptorWS – Versão 1.20

Nova versão 1.20 – Mudança na estrutura Server

Na versão anterior do Raptor,  não era possível logar o contexto da requisição dentro do ServerMethod e nem exibir nenhum Log no form Principal, uma vez que a implementação de cada Server Method estava desconectada ou não tinha acesso aos dados da requisição por exemplo  : qual IP de onde partiu a requisição entre outros dados, não era possível logar essa informação de dentro do ServerMethod, apenas antes de chamá-lo.

Então uma mudança estrutural na construção da parte Server se fez necessária. Foi criada uma Unit HandleContext contendo a classe TServerContext herdada de  de TIdServerContext, onde nela coloquei o o dispatch de métodos REST conforme o tipo e isolei em classe separada os ServerMethods, dessa forma o Core do WebService fica separado  dos ServerMethods de seu negócio.

Essa mudança estrutural permite também que agora você possa ter várias Units ServerMethods separadas com uma responsabilidade única, por exemplo, numa aplicação de Gerenciamento de Escola, poderíamos ter uma unit com ServerMethods para Alunos, outra unit para Professores, outra para Material didático e assim por diante.

Classe TServerContext na Unit HandleContext :TServerContext.jpg

Para essa classe foi atribuída a tarefa de obter os argumentos da requisição e chamar cada operação Rest.

Uma vantagem dessa classe é que estando num nível intermediário e antes da chamada do servermethod, que possa realizar tarefas comuns a todos os ServerMethods, poupando assim  cada ServerMethod de um trabalho repetitivo que seja comum a todos.

Outra vantagem dessa classe é que ela sendo herdada do Contexto da Requisição (TIdServerContext) teríamos todos os dados como IP de onde partiu a conexão, o User Agent, e todos os dados relativos  ao contexto, podendo ser usado para log.

CORS-HEADERS

Outra melhoria foi a adição de CORS-Headers, colaboração de José Benedito, que faz com que o servidor retorne respostas à requisições AJAX CrossDomain.

CORS_HEADERS1

Logando dados do negócio, no ServerMethod

Na tela principal do Server foi adicionado um Log da Aplicação, onde cada ServerMethod loga a operação efetuada, como dados do IP da requisição, Nome do ServerMethod chamado e parâmetros passados ao ServerMethod. Veja o terceiro Memo é o que corresponde ao log da Aplicação (ou do negócio).  Os 2 primeiros referem-se ao servidor.

RaptorWS

A Linha de código que faz a geração de Log é a  “Context.LogBusiness (… ” que pode ser vista em todos os serverMethods :

LogBusiness.jpg

Migração da versão 1.11 para 1.20

Muitas alterações foram feitas nesta versão 1.20, de modo que aqueles que usavam a versão 1.1 teriam muito trabalho para adequar a esta nova estrutura, aqueles que quiserem usar a versão 1.20 tendo já implementado o seus ServerMethods na versão  1.1, baixem a versão 1.20 e tragam o código de cada ServerMethods da versão 1.1 e encaixem no local adequado da versão 1.20.

Download da versão 1.20

DonwloadServer

DonwloadClient

Estudo de Caso – Realizar tarefas comuns a todos os Server methods

Agora vou Exemplificar como Obter o Código do usuário antes da chamada de cada ServerMethod para que possa ser usado por todos os ServerMethods quando necessário, usando a Classe TServerContext.

Supondo que em todos os nossos ServerMethods padronizássemos que o código do usuário fosse passado sempre no 1o. Parâmetro, então poderíamos colocar no CallGETServerMethod antes da chamada de cada ServerMethod, a obtenção do Usuário, aí crio uma classe TUsuario onde preencho o Código do Usuário e passo esse objeto como parâmetro no ServerMethod, veja como ficaria :

CodigoUnico.jpg

Ou se preferir coloque essa implementação comum antes disso, na TServerContext.HandleRequest que é a que chama CallGETServerMethod

ServerMethods com Responsabilidade única

Supondo que num sistema de Gerenciamento de escolas tenhamos ServerMethods agrupados por responsabilidade, um para Alunos e outros para  Professores, colocar todas as responsabilidades numa única classe fica um poço sem fundo, ferindo o princípio SOLID de responsabilidade única que deve ter uma classe, e sacrificando a manutenção futura. Dessa forma você poderia organizar seus server methods em Units Separadas, cada Unit com uma nome de classe distinta  :

foram criadas 2 Units SMAlunos.pas (SM = ServerMethod) e SMProfessores, cada uma com um ServerMethod de nome Consulta. Para facilitar ainda mais coloquei na chamada do navegador o prefixo do nome do objeto, dessa forma o método SMAlunos.Consulta da classe TSMAlunos deverá ser chamado no navegador assim :

http://localhost:8080/SMAlunos.Consulta/fulano

e na CallGetServerMethod instanciaríamos cada classe e chamaremos seu método específico :

RespUnica

Uses :

Uses

Dessa forma podemos organizar os ServerMethods em Units separadas por responsabilidade.

Não é Show ? Espero que gostem e comentem.

Valeu.

25 comentários sobre “RaptorWS – Versão 1.20

  1. Boa tarde Claudio

    Voce teria algum exemplo de como enviar e receber datasets em json usando unidac ou outro componente que nao seja o firedac que nao está disponível na versao Professional do Delphi?

    Curtir

  2. Clap, clap, clap, magnífico.
    Encontrei por acaso seu blog e me surpreendi com essa ideia. Se já não estivesse usando o DataSnap REST creio que usaria sua ideia, parabéns pela iniciativa e mais ainda de compartilhar isto.

    Legal se conseguir usar compressão de dados como o DataSnap faz utilizando ZLib.

    Uma dúvida, é possível utilizar o RaptorWS como módulo do IIS? Como serviço sei que é bem provável que funcione.

    Abraços.

    Curtir

    • Obrigado que bom que gostou. A compressão de dados está prevista como uma melhoria a ser implementada nas próximas versões do produto. Nada complicado só falta mesmo o tempo pra desenvolver. Não conheço o formato do módulo do IIS, preciso estudar para poder fazer essa integração. Coloco na lista para próximas versões.

      Curtir

  3. muito top, gostei bastante, vou tentar implementar em uma aplicação q ja tenho, uso dataSnap, mas vou fazer desta forma com o rest e json, só tenho q ver como vou adaptar no banco de dados, não tem um exemplo com banco de dados?

    Curtir

    • Olá Afonso, Não tenho exemplo com banco ainda. Mas a questão do Banco de dados é bem simples. Uma vez que o Raptor é Stateless (não guarda estado) ele é semelhante ao Life Cycle “Invocation” do DataSnap ou seja a conexão com o banco é feita em cada método do WebService. Então o fluxo seria assim em cada método : 1 – Conecta com o Banco, 2 – Realiza a Query, 3 – Transforma o resultado em JSON, 4 – Fecha a conexão com o Banco.

      Caso ainda não tenha lido dê uma lida nessa página : https://delphisolutions.wordpress.com/2015/12/07/rest-webservice-em-delphi-com-indy-sem-datasnap/

      Curtir

      • muito obrigado pela resposta, é q estou começando agora nessa parte de dataSnap e Rest, e a parte de dataSnap ja peguei meia pronta e adaptei as minhas necessidades, mas show de bola, estou acompanhando suas postagens. tenho alguns exemplos passando query para json, vou tentar fazer. parabéns.

        Curtir

  4. No Delphi Berlin 10.1 os argumentos em TServerContext estão sempre zerados, e o servidor não consegue responder a nenhuma solitação. Alguma idéia da causa?

    function TServerContext.CallGETServerMethod (Argumentos : TArguments) : string;

    Curtir

      • Boa noite Claudio, não sei o que pode ser. Apenas baixei os arquivos tanto client como server, e compilei. E nada. Se pego os executáveis que já estão compilados, funcionam.
        Estranho.

        Curtir

      • Boa noite, antes tarde do que mais tarde.

        Testei agora no Tokyo e obtive o mesmo erro, e é graças as diretivas de compilação, que no momento do desenvolvimento ainda não existia Berlin e Tokyo, no máximo Seattle.

        {$IFDEF VER300} // SEATTLE

        Procurei por todo o projeto e ajustei para a minha versão do Delphi, e agora está OK.

        Estou respondendo aqui para registrar, pois caso alguém passe por isso não desista facilmente de um projeto tão bacana.

        Curtir

      • Obrigado Ricardo, seu comentário é valioso para outras pessoas que possam vir a ter o mesmo problema. Assim que eu tiver um tempo vou retomar esse projeto e adicionar muitas funcionalidades.

        Curtir

    • Olá Anderson, com certeza é possível. A mágica é feita apenas substituindo o retorno da cada método do web-service de JSON para html/angular. Estude os exemplos e você vai entender onde mexer. Não é preciso nem mexer no core do framework, basta colocar essa substituição em cada server method. Boa sorte e depois conte pra nós seu caso de sucesso usando o RaptorWS.

      Curtido por 1 pessoa

  5. Claudio boa tarde.

    Há algum tempo conversei contigo sobre estudar o Raptor WS.
    Baseado nele, fiz um ws (ainda em desenvolvimento), onde uso a RTTI pra achar os métodos e o firedac na busca de dados, usando um ORM caseiro.

    Ficou bem bacana. Obrigado pelo Help.

    Curtir

    • Lucas fiquei interessado na rotina de achar os métodos via RTTI, para no caso incrementar o Raptor. Caso não tenha objeção em compartilhar pode me enviar no cldmag@gmail.com. Se tiver alguma objeção sem problema algum, fico feliz que a partir do Raptor você tenha conseguido fazer o seu.

      Curtir

Deixar mensagem para claudiofs Cancelar resposta