💡 Se gostou deste conteúdo, compartilhe com quem precisa
Visão geral: Criando um Webservice RESTful no Protheus
—
##
Estrutura básica do Webservice REST
WSRESTFUL
. Veja como é feita essa configuração básica:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#INCLUDE "PROTHEUS.CH" #INCLUDE "RWMAKE.CH" #INCLUDE "TBICONN.CH" #INCLUDE "COLORS.CH" #INCLUDE "RPTDEF.CH" #INCLUDE "FWPrintSetup.ch" #Include 'parmtype.ch' #Include "RestFul.CH" #Include "TopConn.CH" #INCLUDE "FILEIO.ch" User Function FBESTA01() Return WSRESTFUL CONSESTQ DESCRIPTION "Serviço REST para consulta de estoque" WSDATA SEGKEY As String WSDATA PFILIAL As String WSDATA PRODUTO As String WSDATA ARMAZEM As String WSMETHOD GET DESCRIPTION "Retorna o estoque do produto informado na URL" WSSYNTAX "/CONSESTQ || /CONSESTQ/{PFILIAL}{PRODUTO}{ARMAZEM}" END WSRESTFUL |
###
Principais pontos dessa estrutura
– **WSRESTFUL**: Define a classe do Webservice.
– **WSDATA**: Mapeia os parâmetros que serão recebidos via URL.
– **WSMETHOD GET**: Define o método HTTP e a rota que será exposta.
—
##
Tratamento da Requisição GET
GET
implementa a lógica para extrair os parâmetros, consultar o banco de dados e devolver os dados em formato JSON:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
WSMETHOD GET WSSERVICE CONSESTQ Local cPFILIAL := Self:PFILIAL Local cPRODUTO := Self:PRODUTO Local cARMAZEM := Self:ARMAZEM Local aArea := GetArea() Local cJson := "" Local aDados := {} If !u_FBSegApp(Self:SEGKEY) Return EndIf ::SetContentType("application/json") aDados := u_FBESTA02(cPFILIAL, cPRODUTO, cARMAZEM, "SB2.B2_COD") oObjCom := Objetos():New(aDados) cJson := FWJsonSerialize(oObjCom) ::SetResponse(cJson) RestArea(aArea) Return(.T.) |
###
O que está acontecendo aqui?
– Validação da chave de segurança com u_FBSegApp
.
– Chamada da função FBESTA02
, responsável pela consulta de dados.
– Serialização dos dados usando FWJsonSerialize
.
– Resposta JSON formatada enviada ao cliente via SetResponse
.
—
##
Consulta ao banco de dados: a função FBESTA02
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
User Function FBESTA02(cPFILIAL, cPRODUTO, cARMAZEM, cOrderBy) Local aRet := {} Local cFiltro := "" If !Empty(cPFILIAL) cFiltro += " AND SB2.B2_FILIAL = '" + cPFILIAL + "' " EndIf If !Empty(cPRODUTO) cFiltro += " AND SB2.B2_COD = '" + UPPER(cPRODUTO) + "' " EndIf If !Empty(cARMAZEM) cFiltro += " AND SB2.B2_LOCAL = '" + cARMAZEM + "' " EndIf // Aqui você pode continuar explicando e depois incluir o código completo original como solicitado |
—
##
Implementação Completa
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
#INCLUDE "PROTHEUS.CH" #INCLUDE "RWMAKE.CH" #INCLUDE "TBICONN.CH" #INCLUDE "COLORS.CH" #INCLUDE "RPTDEF.CH" #INCLUDE "FWPrintSetup.ch" #Include 'parmtype.ch' #Include "RestFul.CH" #Include "TopConn.CH" #INCLUDE "FILEIO.ch" #Define BREAKLINE Chr(13)+Chr(10) /*/{Protheus.doc} FBESTA01 Rest em ADVPL @author FBS Consultoria @since 11/03/2020 @version 1.0 @type function /*/ User Function FBESTA01() Return /*/{Protheus.doc} CONSESTQ Definição da estrutura do webservice @author FBS Consultoria @since 04/06/2019 @type class /*/ WSRESTFUL CONSESTQ DESCRIPTION "Serviço REST para consulta de estoque" WSDATA SEGKEY As String //String que vamos receber via URL WSDATA PFILIAL As String //String que vamos receber via URL WSDATA PRODUTO As String //String que vamos receber via URL WSDATA ARMAZEM As String //String que vamos receber via URL WSMETHOD GET DESCRIPTION "Retorna o estoque do produto informado na URL" WSSYNTAX "/CONSESTQ || /CONSESTQ/{PFILIAL}{PRODUTO}{ARMAZEM}" //Disponibilizamos um método do tipo GET END WSRESTFUL WSMETHOD GET WSSERVICE CONSESTQ //--> Recuperamos o produto informado via URL //--> Podemos fazer dessa forma ou utilizando o atributo ::aUrlParms, que é um array com os parâmetros recebidos via URL (QueryString) Local cPFILIAL := Self:PFILIAL Local cPRODUTO := Self:PRODUTO Local cARMAZEM := Self:ARMAZEM Local aArea := GetArea() Local cJson := "" Local cQuery := "" Local cQueryORA := "" Local aDados := {} Local cRet := "" Local cOrderBy := "SB2.B2_COD" Local cBD := AllTrim(GetMV("MV_FBWEB08")) //AQUI PODE DEFINIR MSSSQL OU ORACLE Local cPag := "10" Local cPAGINA := "" Local cFiltro := "" If !u_FBSegApp(Self:SEGKEY) Return EndIf Conout("WS CONSESTQ") // define o tipo de retorno do método ::SetContentType("application/json") aDados := u_FBESTA02(cPFILIAL, cPRODUTO, cARMAZEM, cOrderBy) oObjCom := Objetos():New(aDados) //Cria um objeto da classe produtos para fazer a serialização na função FWJSONSerialize cJson := FWJsonSerialize(oObjCom) Conout(cJson) // --> Envia o JSON Gerado para a aplicação Client ::SetResponse(cJson) RestArea(aArea) // --> Envia o JSON Gerado para a aplicação Client ::SetResponse(cRet) //RpcClearEnv() RestArea(aArea) Return(.T.) User Function FBESTA02(cPFILIAL, cPRODUTO, cARMAZEM, cOrderBy) Local aRet := {} Local cBD := 'MSSQL' Default cOrderBy := "SB2.B2_COD" Conout("FILIAL: " + cPFILIAL + " PRODUTO: " + cPRODUTO + " ARMAZEM: " + cARMAZEM) cFiltro := "" If ! Empty(cPFILIAL) cFiltro += " AND SB2.B2_FILIAL = '" + cPFILIAL + "' " + BREAKLINE EndIf If ! Empty(cPRODUTO) cFiltro += " AND SB2.B2_COD = '" + UPPER(cPRODUTO) + "' " + BREAKLINE EndIf If ! Empty(cARMAZEM) cFiltro += " AND SB2.B2_LOCAL = '" + cARMAZEM + "' " + BREAKLINE EndIf cQuery := "SELECT B2_QATU " + BREAKLINE cQuery += "FROM " + RetSQLName("SB2") + " as SB2 WITH(NOLOCK) " + BREAKLINE cQuery += "WHERE SB2.D_E_L_E_T_ = '' " + BREAKLINE cQuery += cFiltro cQuery += "ORDER BY " + cOrderBy If cBD == 'ORACLE' cQueryORA := " SELECT ROWNUM + (" + cPag + " * (PAGINA - 1)) AS LINNUM " + BREAKLINE cQueryORA += " ,B.* " + BREAKLINE cQueryORA += " FROM (SELECT COUNT(*) OVER() AS TOTALREG " + BREAKLINE cQueryORA += " ,TRUNC((ROW_NUMBER() OVER(" + cOrderBy + ") - 1) / " + cPag + ") + 1 AS PAGINA " + BREAKLINE cQueryORA += " ,TMP.* " + BREAKLINE cQueryORA += " FROM ( " + BREAKLINE cQueryORA += cQuery cQueryORA += ") TMP " + BREAKLINE cQueryORA += ") B " + BREAKLINE If !Empty(cPAGINA) cQueryORA += " WHERE PAGINA = " + cPAGINA + " " + BREAKLINE EndIf cQuery := cQueryORA EndIf Conout("CONSESTQ cQuery: " + cQuery) If Select("QRY_AUX") > 0 QRY_AUX->(dbCloseArea()) EndIf //Executando consulta e setando o total da régua TCQuery cQuery New Alias "QRY_AUX" Count to nTotal QRY_AUX->(DbGoTop()) While ! QRY_AUX->(Eof()) aAdd(aRet, { QRY_AUX->B2_QATU,; }) QRY_AUX->(dbSkip()) EndDo QRY_AUX->(dbCloseArea()) Return aRet |
—
##
—
Fernando Bueno
Consultor em FBSOLUTIONS
Sou consultor na área de implantação de sistemas ERP, com experiência na análise e implantação de projetos de sistemas, configurando a estrutura do software, capacitando usuários-chaves, ministrando treinamentos e workshops.
Atuando desde 2005 no mercado de tecnologia, desenvolvendo e implantando e sistemas gerenciais, sistemas e sites web e ecommerce.
Siga-me no Linked In
Atuando desde 2005 no mercado de tecnologia, desenvolvendo e implantando e sistemas gerenciais, sistemas e sites web e ecommerce.
Siga-me no Linked In