REST e Data Provider
Autor: Douglas Oliveira | Publicado: 2017-02-11T15:17:00-08:00

Fechando o ciclo dos webservices do tipo REST falta ainda discutir um pouco a respeito da obtenção de uma lista de registros de um certo sistema, ou kb, para que possamos ter informação em nosso sistema cliente.

Em nossos artigos anteriores tratamos a respeito da metodologia para se desenvolver o CRUD utilizando uma transação:&nbsp;REST &amp; SOAP, porém este modelo nos permite atuar sobre determinado registro apenas. Discutimos inclusive a importância de se estabelecer um mecanismo de segurança, que optamos pelo GAM pela praticidade e recursos. O último tratou de uma ferramenta de apoio para que possamos testar o serviço remotamente, REST client. O que falta agora é discutir como acessar informações no servidor, trazendo uma coleção de registros ao mesmo tempo.


Data Provider
Este recurso está passando por algumas transformações importantes, e desde o seu nascimento, a então Artech já dava as premissas de uma revolução no modelo de programação com seu descreva ao invés de programar.

Creio que a grande maioria dos genexandos já se depararam com este objeto, talvez apenas não avançaram para torná-lo um serviço REST, então vamos dedicar alguns parágrafos para explicá-lo. O Wiki Genexus traz muito boas informações sobre este tema.


1) Começamos montando um SDT&nbsp;
Criar um SDT com a estrutura da informação desejada é o primeiro passo para exportarmos informação. E aqui vale inclusive arrastar a transação para o editor de SDT para que este inclua todos os campos desta no objeto que estamos construindo.

Seguindo a linha dos exemplos anteriores, vamos gerar uma lista de empresas a partir da transação Empresa. O SDT é o mesmo do exemplo em&nbsp;REST &amp; SOAP





2) Criando o Data Provider
O próximo passo é arrastar o SDT para dentro do objeto Data Provider. Se encontrar alguma dificuldade para remover as atribuições padrões do Genexus temos aqui&nbsp;a solução&nbsp;Krueger.





A aplicação de filtros where é permitida, e neste caso teremos que enviar parâmetros para o serviço REST. Não esqueça de incluir uma regra Parm com os parâmetros


parm(&amp;EmpresaId);


3) Definindo as propriedades do DP
Além de definir o Output como Collection=true, também será necessário expor o objeto como Serviço REST.






4) Montando o cliente
Uma segunda KB ou qualquer programa externo poderá consultar nosso DP REST, e claro, mantendo o mesmo esquema de proteção do GAM, o cliente deverá realizar primeiramente o login, para em seguida poder executar o DP. Uma chamada ao serviço /oauth, passando-se os parâmetros corretos, realiza a proposta. Como informamos no artigo anterior o client_id é obtido no GamHome.

sub 'login'
&nbsp;&amp;httpclient.Host = 'localhost/'
&nbsp;&amp;httpclient.Port = 80
&nbsp;&amp;httpclient.BaseUrl = '/Kb.NetEnvironment/oauth/'
&nbsp;&amp;addstring ='client_id=068868de058b4798bd3b90f696fa37f8&amp;grant_type=password&amp;scope=FullControl&amp;username=admin&amp;password=admin123'
&nbsp;&amp;httpclient.AddHeader("Content-Type", "application/x-www-form-urlencoded")
&nbsp;&amp;httpclient.AddString(&amp;addstring)
&nbsp;&amp;httpclient.Execute('POST','access_token')
&nbsp;&amp;AccessTokenSDT.FromJson(&amp;httpclient.ToString())
&nbsp;&amp;websession.set('TOKEN', &amp;AccessTokenSDT.access_token)
EndSub

Para completar o processo de login e necessário obter o token, e para isto programamos o AccessTokenSDT que formata a respota do GAM. Se estivermos tratando de Genexus para Genexus, os objetos podem ser exportados e importados na Kb cliente, porém, para outros ambientes teremos que definir, na linguagem específica a respectiva estrutura.




Armazenamos o Token na sessão para poder acessar seu valor quando necessário.



&amp;websession.set('TOKEN', &amp;AccessTokenSDT.access_token)

A chamada ao Data Provider deve ser realizado passando-se o token.

&amp;httpclient.AddHeader('Authorization','OAuth ' + &amp;websession.get('TOKEN'))

Em seguida uma variável querystring é programada para informar o parâmetro a ser passado. Observe que o parametro deve ser declarado neste modelo,&nbsp;"?EmpresaId=" + trim(&amp;EmpresaId.ToString()). O Data Provider é incluído no querystring,&nbsp;empresadp.

&amp;querystring='empresadp' + "?EmpresaId=" + trim(&amp;EmpresaId.ToString())

O código completo da chamada é apresentado a seguir.

Event Enter
 do 'login' 
 
 &amp;httpclient.Host = 'localhost/'
 &amp;httpclient.Port = 80
 &amp;httpclient.BaseUrl = '/Kb.NetEnvironment/rest/'
 &amp;httpclient.AddHeader('content-type','application/json')
 &amp;httpclient.AddHeader('Authorization','OAuth ' + &amp;websession.get('TOKEN'))
 &amp;querystring='empresadp' + "?EmpresaId=" + trim(&amp;EmpresaId.ToString())
 &amp;httpclient.Execute('GET', &amp;querystring)
 &amp;resposta = &amp;httpclient.ToString()
Endevent


Para transformar a resposta em uma variável SDT é possível desde que definido. Fizemos isto no primeiro passo, ao criar o EmpresaSDT. Será necessário é transferir o objeto da Kb onde se encontra o Data Provider para a Kb cliente.



Uma variável do tipo EmpresaSDT deve ser criada como Collection=true. E, em seguida, um FromJson resolverá a parada.



&amp;EmpresaSDT.FromJson(&amp;httpclient.ToString())



O resultado disso? temos os registros recuperados da tabela Empresa, filtrados pela variável &amp;EmpresaSDT. Desta forma podemos 'consultar' esta tabela em memória, na máquina cliente.



Fechando a conta

Temos muitos recursos interessantes que poderemos utilizar para solucionar nossos problemas de programação. O uso de webservices é importante porque toda lógica de proteção dos dados se encontra sob o domínio da Kb que fornece o serviço. Diferentemente de um acesso direto à tabela, por meio de um DataView, os webservices permitem um maior controle sobre o acesso e autorizações sobre as operações que cada sistema cliente terá.



Talvez não sirva para todas as situações, mas com certeza, para cenários de multiplos sistemas que necessitam trocar informações é uma excelente aposta.



Maiores informações:


http://wiki.genexus.com/commwiki/servlet/wiki?30737,HowTo%3A+Consuming+a+Rest+Data+Provider,&nbsp;
http://wiki.genexus.com/commwiki/servlet/wiki?28213,Toc%3ARest+web+services+in+GeneXus,
http://wiki.genexus.com/commwiki/servlet/wiki?20977,Consuming+REST+Data+Providers+in+Genexus, 



Acesso aos exemplos, formato XPZ:


REST_Servicos: Kb fornecedora dos dados
REST_Cliente: Kb cliente que chama o Data Provider.


Gerador:



.Net a chamada ao serviço REST não precisa obedecer rigorosamente o nome do DP, podendo ser utilizado letras maiusculas ou minúsculas
Java exige que o nome do serviço obedeça o case das fontes.