Hoje vamos demonstrar a diferença entre o REST clássico com WSRestFul e o novo utilizando Annotation.
Para quem já desenvolveu WebServices em AdvPL, sabe que para utilizarmos REST, tínhamos que fazer usando WSRestFul. Mas com a vinda do TL++, nós podemos fazer de modo mais simples com Annotation.
Além das configurações no .ini (no fim desse artigo vou deixar um link de referência do TDN), as diferenças estão na estrutura das funcionalidades, enquanto no WSRestFul, segue uma estrutura parecida com Classe, na nova, é usada uma estrutura de função com User Function.
Eu montei um pequeno exemplo de GET em ambos os casos.
Abaixo o exemplo com WSRestFul, fonte WSGrupoProdAnt.prw:
//Bibliotecas #Include "Totvs.ch" #Include "RESTFul.ch" #Include "TopConn.ch" /*/{Protheus.doc} WSRESTFUL WSGrupoProdAnt WS Grupo de Produtos @author Atilio @since 02/10/2022 @version 1.0 @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ WSRESTFUL WSGrupoProdAnt DESCRIPTION 'WS Grupo de Produtos' //Atributos WSDATA id AS STRING //Métodos WSMETHOD GET ID DESCRIPTION 'Retorna o registro pesquisado' WSSYNTAX '/WSGrupoProdAnt/get_id?{id}' PATH 'get_id' PRODUCES APPLICATION_JSON END WSRESTFUL /*/{Protheus.doc} WSMETHOD GET ID Busca registro via ID @author Atilio @since 02/10/2022 @version 1.0 @param id, Caractere, String que será pesquisada através do MsSeek @obs Codigo gerado automaticamente pelo Autumn Code Maker @see http://autumncodemaker.com /*/ WSMETHOD GET ID WSRECEIVE id WSSERVICE WSGrupoProdAnt Local lRet := .T. Local jResponse := JsonObject():New() Local cAliasWS := 'SBM' //Se o id estiver vazio If Empty(::id) //SetRestFault(500, 'Falha ao consultar o registro') //caso queira usar esse comando, você não poderá usar outros retornos, como os abaixo Self:setStatus(500) jResponse['errorId'] := 'ID001' jResponse['error'] := 'ID vazio' jResponse['solution'] := 'Informe o ID' Else DbSelectArea(cAliasWS) (cAliasWS)->(DbSetOrder(1)) //Se não encontrar o registro If ! (cAliasWS)->(MsSeek(FWxFilial(cAliasWS) + ::id)) //SetRestFault(500, 'Falha ao consultar ID') //caso queira usar esse comando, você não poderá usar outros retornos, como os abaixo Self:setStatus(500) jResponse['errorId'] := 'ID002' jResponse['error'] := 'ID não encontrado' jResponse['solution'] := 'Código ID não encontrado na tabela ' + cAliasWS + ', informe outro código' Else //Define o retorno jResponse['grupo'] := (cAliasWS)->BM_GRUPO jResponse['desc'] := (cAliasWS)->BM_DESC EndIf EndIf //Define o retorno Self:SetContentType('application/json') Self:SetResponse(jResponse:toJSON()) Return lRet
Abaixo o exemplo com Annotation, fonte WSGrupoProdNov.tlpp:
//Bibliotecas #Include "Tlpp-Core.th" #Include "Tlpp-Rest.th" /*/{Protheus.doc} User Function WSGrupoProdNovGetUnico Exemplo de WS para buscar um grupo de produto conforme código @type Function @author Atilio @since 02/10/2022 /*/ @Get("WsGrupoProdNov/get/unico/") User Function WSGrupoProdNovGetUnico() Local jResponse := JsonObject():New() As Json Local jPath As Json Local cAliasWS := 'SBM' As Character //Busca os dados que o usuário informou jPath := JsonObject():New() jPath := oRest:getQueryRequest() //Caso haja conteúdo e não esteja vazio o ID If jPath != Nil .And. ! Empty(jPath:GetJsonObject('id')) DbSelectArea(cAliasWS) (cAliasWS)->(DbSetOrder(1)) //Se não encontrar o registro If ! (cAliasWS)->(MsSeek(FWxFilial(cAliasWS) + jPath:GetJsonObject('id') )) oRest:setStatusCode(500) jResponse['errorId'] := 'ID002' jResponse['error'] := 'ID não encontrado' jResponse['solution'] := 'Código ID não encontrado na tabela ' + cAliasWS + ', informe outro código' //Define o retorno Else jResponse['grupo'] := (cAliasWS)->BM_GRUPO jResponse['desc'] := (cAliasWS)->BM_DESC EndIf //Do contrário, irá retornar uma mensagem que não foi encontrado Else oRest:setStatusCode(500) jResponse['errorId'] := 'ID001' jResponse['error'] := 'ID vazio' jResponse['solution'] := 'Informe o ID' EndIf //Encerra retornando o JSON oRest:setKeyHeaderResponse('Content-Type','application/json') oRest:setResponse(jResponse:toJSON()) Return
Referências:
- Configuração completa do novo REST no AppServer
- REST server (tlppCore) – TDN
- Migração WsRESTful para REST tlppCore
Bom pessoal, por hoje é só.
Abraços e até a próxima.