|
WX - Exemplo de um Webservice REST usando o Webdev |
Iniciado por adrianoboller, mai., 10 2016 8:47 PM - 6 respostas |
| |
| | | |
|
| |
Membro registado 3.657 mensagems Popularité : +175 (223 votes) |
|
Publicado em maio, 10 2016 - 8:47 PM |
Prezados,
Vamos fazer aqui um passo a passo de como trabalhar com um Webservice REST.
Bom afinal, o que é um Webservice Rest?
SOAP
SOAP é um protocolo de transferência de mensagens em formato XML para uso em ambientes distribuídos. O padrão SOAP funciona como um tipo de framework que permite a interoperabilidade entre diversas plataformas com mensagens personalizadas.
Aplicando este padrão em Web Services, geralmente usa-se o WSDL para descrever a estrutura das mensagens SOAP e as ações possíveis em um endpoint.
Uma das maiores vantagens disso é que várias linguagens e ferramentas conseguem ler e gerar mensagens facilmente. Várias linguagens de programação permitem a geração de objetos de domínio, Stubs e Skeletons a partir da definição do WSDL, permitindo a comunicação remota via RPC através de chamadas a métodos remotos, inclusive com argumentos complexos, como se fossem chamadas locais.
O problema desse padrão, é que ele adiciona um overhead considerável, tanto por ser em XML quanto por adicionar muitas tags de meta-informação. Além disso, a serialização e desserialização das mensagens pode consumir um tempo considerável. REST
REST é outro um protocolo de comunicação, baseado no protocolo de hipermídia HTTP. Porém ele não impõe restrições ao formato da mensagem, apenas no comportamento dos componentes envolvidos.
A maior vantagem do protocolo REST é sua flexibilidade. O desenvolvedor pode optar pelo formato mais adequado para as mensagens do sistema de acordo com sua necessidade específica. Os formatos mais comuns são JSON, XML e texto puro, mas em teoria qualquer formato pode ser usado.
Isso nos leva a outra vantagem: quase sempre Web Services que usam REST são mais "leves" e, portanto, mais rápidos.
O problema com o REST pode surgir justamente por causa de suas vantagens. Como a definição do corpo de dados fica totalmente a cargo do desenvolvedor, os problemas de interoperabilidade são mais comuns. SOAP ou REST?
Aviso: Esta é uma opinião pragmática.
Em geral, SOAP é uma boa opção para instituições com padrões rígidos e ambientes complexos (várias plataformas e sistemas). Muitas ferramentas corporativas (como ESB) tiram vantagem do padrão e possibilitam filtrarem, enfileiramento, classificação e redirecionamento das mensagens trocadas entre sistemas.
No restante, para uso no dia-a-dia, não vejo motivos concretos para não usar REST e JSON. Praticamente todas as plataformas e linguagens modernas que conheço suportam esses conceitos e a solução final é muito mais simples do que o equivalente em SOAP.
Além disso, integrações com alto volume de requisições são inviáveis em SOAP. REST é capaz de atender volume e complexidade sem dificuldades, exigindo apenas um mínimo de experiência do desenvolvedor para estabelecer e reforçar os padrões adequados.
O REST é simples de entender e pode ser adotado em praticamente qualquer cliente ou servidor com suporte a HTTP/HTTPS. Os desenvolvedores que o utilizam citam, como principais vantagens a facilidade no desenvolvimento, o aproveitamento da infraestrutura web existente e um esforço de aprendizado pequeno.
Por outro lado, o SOAP, avô das interfaces de serviços web, não deixará de ser usado tão cedo. Com o SOAP v 1.2, muitas das deficiências percebidas nessa tecnologia foram corrigidas e aumentou a facilidade de uso. Além disso, a sigla SOAP deixou de representar "Simple Object Access Protocol". Na especificação 1.2 da W3C, SOAP é apenas o nome da especificação.
Utilizar o SOAP 1.2 traz uma carga adicional não encontrada ao usar REST, mas há também vantagens. Primeiramente o SOAP é baseado em XML, de três formas: o envelope, que define o conteúdo da mensagem e informa como processá-la; um conjunto de regras de codificação para os tipos de dados; e o layout para os procedimentos de chamadas e respostas. Esse "envelope" é enviado por meio de (por exemplo) HTTP/HTTPS. E uma RPC (Remote Procedure Call) é executada, e o envelope retorna com as informações do documento XML formatado.
Uma das vantagens do SOAP é o uso de um método de transporte "genérico". Enquanto que o REST faz uso de HTTP/HTTPS, o SOAP pode usar qualquer meio de transporte existente para enviar sua requisição, desde SMTP até mesmo JMS (Java Messaging Service). No entanto, uma desvantagem percebida no uso de XML é a sua natureza prolixa e o tempo necessário para analisar o resultado apresentado.
Mas uma história não contada é que ambas as tecnologias podem ser misturadas e combinadas. O REST é fácil de entender e extremamente acessível porém faltam padrões, e a tecnologia é considerada apenas uma abordagem arquitetural. Em comparação, o SOAP é um padrão da indústria, com protocolos bem definidos e um conjunto de regras bem estabelecidas.
Pode-se afirmar, então, que casos onde o REST funciona bem são:
Situações em que há limitação de recursos e de largura de banda: A estrutura de retorno é em qualquer formato definido pelo desenvolvedor e qualquer navegador pode ser usado. Isso porque a abordagem REST usa o padrão de chamadas GET, PUT, POST e DELETE. O REST também pode usar objetos XMLHttpRequest (a base do velho AJAX) que a maioria dos navegadores modernos suporta.
Operações totalmente sem-estado: se uma operação precisa ser continuada, o REST não será a melhor opção. No entanto, se forem necessárias operações de CRUD stateless (Criar, Ler, Atualizar e Excluir), o REST seria a melhor alternativa.
Situações que exigem cache: se a informação pode ser armazenada em cache, devido à natureza da operação stateless do REST, esse seria um cenário adequado para a tecnologia.
Essas três situações abrangem muitas soluções. Então por que ainda precisamos considerar o uso do SOAP? Mais uma vez, o SOAP é bastante maduro e bem definido e vem com uma especificação completa. Já a abordagem REST é apenas isso: uma abordagem. Está totalmente aberta. Por isso ao se encontrar uma das situações abaixo, o SOAP pode ser uma ótima solução:
Processamento e chamada assíncronos: se o aplicativo precisa de um nível garantido de confiabilidade e segurança para a troca de mensagens, então o SOAP 1.2 oferece padrões adicionais para esse tipo de operação como por exemplo o WSRM (WS-Reliable Messaging).
Contratos formais: se ambos os lados (fornecedor e consumidor) têm que concordar com o formato de intercâmbio de dados, então o SOAP 1.2 fornece especificações rígidas para esse tipo de interação.
Operações stateful: para o caso de o aplicativo precisar de informação contextual e gerenciamento de estado com coordenação e segurança, o SOAP 1.2 possui uma especificação adicional em sua estrutura que apoia essa necessidade (segurança, transações, coordenação etc.). Comparativamente, usar o REST exigiria que os desenvolvedores construíssem uma solução personalizada.
Como se vê, cada uma das abordagens tem sua utilidade. Ambas têm problemas nos quesitos de segurança, camadas de transporte etc.; mas ambas podem realizar o trabalho necessário e trazem sua contribuição para o desenvolvimento de aplicações web.
Fonte do exemplo apresentado no webinar "A oferta de serviços sob a forma de serviços Webdev: Webservice REST" Publicado por Jérôme AERTS
http://repository.windev.com
http://repository.windev.com/resource.awp…
RESTSend (Função) Envia um pedido REST e aguarda a resposta do servidor.
cMyRequest é restRequest cMyRequest ..URL = "<server address>" cMyResponse is restResponse = RESTSend ( cMyRequest ) IF ErrorOccurred THEN Error ( ErrorInfo ( errFullDetails )) ELSE Info ( cMyResponse ..Content) END
http://help.windev.com/en-US/…
RestResponse (tipo Variável) O RestResponse tipo é usado para definir todas as características avançadas de uma resposta durante o sono. As características desta resposta pode ser definido e modificado por várias propriedades WLanguage. Nota : Ver declarar uma variável para obter mais detalhes.
cMyRequest é restRequest cMyRequest ..URL = "http://www.windev.com" cMyResponse is restResponse = RESTSend ( cMyRequest ) IF ErrorOccurred THEN Error ( ErrorInfo ( errFullDetails )) ELSE Info ( cMyResponse ..Content) END
http://help.windev.com/en-US/…
restRequest (Tipo de variável) O restRequest tipo é usado para definir as características avançadas de um pedido REST. As características do presente pedido de resto pode ser definido e modificado por várias propriedades WLanguage. Nota : Ver declarar uma variável para obter mais detalhes.
cMyRequest é restRequest cMyRequest ..URL = "http://www.windev.com" cMyResponse is restResponse = RESTSend ( cMyRequest ) IF ErrorOccurred THEN Error ( ErrorInfo ( errFullDetails )) ELSE Info ( cMyResponse ..Content) END
http://help.windev.com/en-US/…
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 9949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 3.657 mensagems Popularité : +175 (223 votes) |
|
Publicado em maio, 10 2016 - 9:29 PM |
Prezados,
Aqui o Exemplo do SERVIDOR Webservice REST:
Crie um projeto Dynamic Webdev [x]
Código da Pagina Principal
Procedure MaPage()
gsNomDonnées est une chaîne=PageParamètre("nomdonnees") gsID est une chaîne=SansCaractère(PageParamètre("id"),"/")
gsDonnéesARenvoyer est une chaîne ANSI gsStatus est une chaîne gsVerbe est une chaîne
gsVerbe=SysEnvironnement("REQUEST_METHOD") gsVerbe=Remplace(gsVerbe,"REQUEST_METHOD=","")
SELON gsNomDonnées CAS ~="produits" (gsStatus,gsDonnéesARenvoyer)=GestionProduits(gsVerbe,gsID) CAS ~="fournisseurs" gsStatus="404" AUTRE CAS gsStatus="403" FIN
PageEcritEntêteHTTP("Status", gsStatus)
ChaîneAffiche(gsDonnéesARenvoyer,"text/json")
Procedure GestionProduits
Procedure GestionProduits(pVerbe est une chaîne,pIDRessource est une chaîne)
sStatus est une chaîne sDonnéesàRenvoyer est une chaîne ANSI
StProduitSimple est une structure Reference est une chaîne LibProd est une chaîne <mapping=LibProd> FIN
StProduitComplet est une structure Reference est une chaîne LibProd est une chaîne Description est une chaîne PrixHT est un monétaire Photo est un Buffer <Sérialise=Faux> CodeBarreFabricant est une chaîne FIN
SELON pVerbe CAS "GET" SI pIDRessource="" ALORS tabProduits est un tableau de StProduitSimple FichierVersTableau(tabProduits,Produit) Sérialise(tabProduits,sDonnéesàRenvoyer,psdJSON) sStatus="200" SINON HLitRecherche(Produit,Reference,pIDRessource,hIdentique) SI HTrouve() ALORS ProduitDemandé est un StProduitComplet FichierVersMémoire(ProduitDemandé,Produit) Sérialise(ProduitDemandé,sDonnéesàRenvoyer,psdJSON) sStatus="200" SINON sStatus="404" FIN FIN CAS "POST" SI pIDRessource="" ALORS sDonnéesReçues est une chaîne sDonnéesReçues=PageParamètre(paramBuffer) stProduitàAjouter est un StProduitComplet QUAND EXCEPTION DANS Désérialise(stProduitàAjouter,sDonnéesReçues,psdJSON) FAIRE sStatus="406" SINON MémoireVersFichier(stProduitàAjouter,Produit) HAjoute(Produit) sStatus="200" FIN SINON sStatus="405" FIN CAS "PUT" SI pIDRessource="" ALORS sStatus="405" SINON HLitRecherche(Produit,Reference,pIDRessource,hIdentique) SI HTrouve() ALORS sDonnéesReçues est une chaîne sDonnéesReçues=PageParamètre(paramBuffer) stProduitàAjouter est un StProduitComplet QUAND EXCEPTION DANS Désérialise(stProduitàAjouter,sDonnéesReçues,psdJSON) FAIRE sStatus="406" SINON MémoireVersFichier(stProduitàAjouter,Produit) HModifie(Produit) sStatus="200" FIN SINON sStatus="404" FIN FIN CAS "DELETE" SI pIDRessource="" ALORS sStatus="405" SINON HLitRecherche(Produit,Reference,pIDRessource,hIdentique) SI HTrouve() ALORS HSupprime(Produit) sStatus="200" SINON sStatus="404" FIN FIN AUTRE CAS sStatus="403" FIN
RENVOYER(sStatus,sDonnéesàRenvoyer)
RETOQUE FINAL
Definir os paramentros de execucao da procedure REST
Menu Project, opção: Referencing - item: Configure the URL Rewriting
Adicione esses parametros
OK
Simples assim, esta feito um Webservice REST, bem diferente do Webservice SOAP que vai um XML dentro do Envelope SOAP
Espero que tenham entendido, esse material foi produzido pelo Sales Manager sr Jerome Aerts da Pcsoft.
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 9949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/Mensagem modificada, maio, 10 2016 - 10:22 PM |
| |
| |
| | | |
|
| | |
| |
Membro registado 3.657 mensagems Popularité : +175 (223 votes) |
|
Publicado em maio, 10 2016 - 10:07 PM |
Prezados,
Aqui o Exemplo do Servidor Webservice REST:
Crie um projeto WINDEV DESKTOP STANDALONE 32 BITS = CLIENTE DO WEBSERVICE ACIMA
TELA:
GLOBAL EMBED AO ABRIR A JANELA:
Procedure MaFenêtre()
StProduitSimple est une structure Reference est une chaîne LibProd est une chaîne FIN
StProduitComplet est une structure Reference est une chaîne LibProd est une chaîne Description est une chaîne PrixHT est un monétaire Photo est un Buffer <Sérialise=Faux> CodeBarreFabricant est une chaîne FIN
gtabListeProduit est tableau de StProduitSimple gDétailProduit est un StProduitComplet
MaFenêtre..Plan=1
BOTAO CONSULTAR
DemandeListeProduits est un restRequête RecupèreListeProduits est un restRéponse
DemandeListeProduits.URL="http://localhost/api/produits.awp" DemandeListeProduits.Méthode=httpGet
RecupèreListeProduits=RESTEnvoie(DemandeListeProduits)
QUAND EXCEPTION DANS Désérialise(gtabListeProduit,RecupèreListeProduits.Contenu,psdJSON) FAIRE Erreur("Incompatibilité dans le format récupéré") SINON TableAffiche(TABLE_Produits,taInit) Message(RecupèreListeProduits.CodeEtat) FIN
BOTAO >>
MaFenêtre..Plan++
Simples assim, esta feito um Cliente que vai consumir um Webservice REST, bem diferente do Webservice SOAP que vai um XML dentro do Envelope SOAP, sendo necessário a leitura das tags Xml.
Espero que tenham entendido, esse material foi produzido pelo Sales Manager sr Jerome Aerts da Pcsoft.
FONTE PARA DOWNLOAD
http://repository.windev.com/resource.awp…
VIDEO EXPLICATIVO
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 9949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/Mensagem modificada, maio, 10 2016 - 10:31 PM |
| |
| |
| | | |
|
| | |
| |
Membro registado 3.657 mensagems Popularité : +175 (223 votes) |
|
Publicado em julho, 25 2016 - 9:26 PM |
Outro exemplo:
ResCode is Buffer lstlotLocal is ResultLoteLocal
sHttpQuery is string
sSistema is string ="999999" sAssinatura is string = "xyxyxyxyxyxyxyxyxyxyyxxyyxyxy" sUnidade is string = "999"
bufBUser is Buffer = "MyUser" bufBPassword is Buffer = "XYXYXYXYXYXYXYYXYXYXYX"
bufSAuthenticacaoBasc is Buffer = Crypt(StringBuild("%1:%2",bufBUser,bufBPassword), "", cryptNone )
sCodContange is string sCodLocal is string
LooperDeleteAll(LOOP_LOTESCONTAGEM)
HTTPCreateForm("FORM") HTTPAddParameter( "FORM","sistema",sSistema) HTTPAddParameter( "FORM","assinatura",sAssinatura) HTTPAddParameter( "FORM","unidade,",sUnidade)
IF NoSpace( EDT_CODLOTE)="" THEN
sHttpQuery = URLEncode(StringBuild ("https://Seu _dominio:sua_porta/Sua API?sistema=%1&assinatura=%2&unidade=%3",sSistema,sAssinatura,sUnidade))
ELSE sCodContange = ExtractString(EDT_CODLOTE,1,"-",FromBeginning) sCodLocal = ExtractString(EDT_CODLOTE,2,"-",FromBeginning) IF sCodLocal = EOT OR sCodLocal="" THEN Info("Favor informar código do local") RETURN END
HTTPAddParameter( "FORM","Parametro_1",sCodContange) HTTPAddParameter( "FORM","Parametro_1",sCodLocal) sHttpQuery = URLEncode( StringBuild( "https://Seu _dominio:sua_porta/Sua_API?sistema=%1&assinatura=%2&unidade=%3&contagem=%4&local=%5",sSistema,sAssinatura,sUnidade,sCodContange,sCodLocal)) END
<Compile IF ConfigurationType=Android OR ConfigurationType=iOS> HTTP.IgnoreError =httpIgnoreInvalidCertificateName <END>
ResStart is boolean = HTTPSendForm("FORM","Sua_Dominio",httpPost,"","Authorization: Basic" + bufSAuthenticacaoBasc ,"application/json")
ResStart = HTTPSendForm("FORM",sHttpQuery,httpGet,"","Authorization: Basic " + bufSAuthenticacaoBasc ,"application/json")
IF ResStart = True THEN ResCode= HTTPGetResult()
IF ResCode <> "" THEN Deserialize(lstlotLocal,ResCode,psdJSON)
FOR i = 1 TO ArrayCount(lstlotLocal.lista) LooperAddLine(LOOP_LOTESCONTAGEM,lstlotLocal.lista[i].idContagem,lstlotLocal.lista[i].descricaoLocal,lstlotLocal.lista[i].qtdNiveis,lstlotLocal.lista[i].qtdEndereco,lstlotLocal.lista[i].qtdProdutos) END ELSE Info("Registro não encontrado!") <Compile IF ConfigurationType=Android> SetFocus(EDT_CODLOTE) <END> END Error(ErrorInfo(errFullDetails )) END
CASE EXCEPTION: Error( ExceptionInfo(errFullDetails))
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 9949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 3.657 mensagems Popularité : +175 (223 votes) |
|
Publicado em janeiro, 16 2017 - 3:13 PM |
Procedure GestionProduits(pVerbe is string, pIDRessource is string)
sStatus is string
sDonnéesàRenvoyer is string ANSI
StProduitSimple is structure Reference is string LibProd is string <mapping=LibProd> END
StProduitComplet is structure Reference is string LibProd is string Description is string PrixHT is currencies Photo is Buffer <Sérialise=Faux> CodeBarreFabricant is string END
SWITCH pVerbe
CASE "GET" IF pIDRessource="" ALORS tabProduits is tableau de StProduitSimple FileToArray(tabProduits,Produit) Serialize(tabProduits,sDonnéesàRenvoyer,psdJSON) sStatus="200" ELSE HReadSeekFirst(Produit,Reference,pIDRessource,hIdentique) IF HFound() ALORS ProduitDemandé est un StProduitComplet FileToMemory(ProduitDemandé,Produit) Serialize(ProduitDemandé,sDonnéesàRenvoyer,psdJSON) sStatus="200" ELSE sStatus="404" END END CASE "POST" IF pIDRessource="" ALORS sDonnéesReçues is string sDonnéesReçues=PageParameter(paramBuffer) stProduitàAjouter est un StProduitComplet QUAND EXCEPTION DANS Deserialize(stProduitàAjouter,sDonnéesReçues,psdJSON) FAIRE sStatus="406" ELSE MemoryToFile(stProduitàAjouter,Produit) HAdd(Produit) sStatus="200" END ELSE sStatus="405" END CASE "PUT" SI pIDRessource="" ALORS sStatus="405" ELSE HReadSeekFirst(Produit,Reference,pIDRessource,hIdentique) SI HFound() ALORS sDonnéesReçues is string sDonnéesReçues=PageParameter(paramBuffer) stProduitàAjouter est un StProduitComplet WHEN EXCEPTION IN Deserialize(stProduitàAjouter,sDonnéesReçues,psdJSON) FAIRE sStatus="406" ELSE MemoryToFile(stProduitàAjouter,Produit) HModify(Produit) sStatus="200" END ELSE sStatus="404" END END CASE "DELETE" IF pIDRessource="" ALORS sStatus="405" ELSE HReadSeekFirst(Produit,Reference,pIDRessource,hIdentique) IF HFound() ALORS HDelete(Produit) sStatus="200" ELSE sStatus="404" END END OTHER CASE: sStatus="403" END
RESULT(sStatus,sDonnéesàRenvoyer)
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 9949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 3.657 mensagems Popularité : +175 (223 votes) |
|
Publicado em janeiro, 17 2017 - 2:37 PM |
tabListeProduit is Variant
DemandeListeProduits is restRequest RecupereListeProduits is restResponse
DemandeListeProduits.URL = "http://localhost/api/produits.awp" DemandeListeProduits.Méthode=httpGet
RecupereListeProduits = RESTSend(DemandeListeProduits)
WHEN EXCEPTION IN Deserialize(tabListeProduit, RecupereListeProduits.Contenu, psdJSON) FAIRE Error("Incompatibile dans le format recupere") ELSE Message("ok") END
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 9949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | |
| |
Membro registado 3.657 mensagems Popularité : +175 (223 votes) |
|
Publicado em maio, 11 2017 - 4:27 PM |
-- Adriano José Boller ______________________________________________ Consultor e Representante Oficial da PcSoft no Brasil +55 (41) 99949 1800 adrianoboller@gmail.com skype: adrianoboller http://wxinformatica.com.br/ |
| |
| |
| | | |
|
| | | | |
| | |
|