Rafael,
Existem diversos problemas em seu exemplo, tais como:
- Declaração de classe produtos no fonte, mas sem utilização.
- Utilização da função FWJsonDeserialize, essa função está depreciada.
- Utilização da função
FWMVCRotAuto
já tendo o modelo instanciado e pronto para ser trabalhado. - Criação do método POST esperando receber informações na URL:
{Fields}
, mas isso é uma inserção, ainda não existe nada pra ser acessado. - Abrir o ambiente dentro do método POST com o
PREPARE ENVIRONMENT
. - Na função getJson, a criação do json está sendo feita com um bloco de código:
{|| JsonObject():New()}
- Você pegou a área corrente antes de manipular a SB1 e restaurou a mesma, correto, porém você não fez o mesmo para a área da SB1, que é exatamente a tabela que você manipulou.
- Includes sem utilização, como o
tbiconn.ch
.
Veja aqui um exemplo com as correções dos erro citados acima:
#include "protheus.ch"
#include "fwmvcdef.ch"
#include "restful.ch"
//-------------------------------------------------------------------
/*{Protheus.doc} Produtos1
API para inserção e consulta de produtos (SB1)
@author Daniel Mendes
@since 06/07/2020
@version 1.0
*/
//-------------------------------------------------------------------
WSRESTFUL Produtos1 DESCRIPTION "Serviço REST para manipulação de Produtos"
WSDATA CodProduto As String
WSMETHOD GET DESCRIPTION "Retorna o produto informado na URL" WSSYNTAX "/PRODUTOS1"
WSMETHOD POST DESCRIPTION "Retorna o produto informado na URL" WSSYNTAX "/PRODUTOS1" PATH "/PRODUTOS1" PRODUCES APPLICATION_JSON
END WSRESTFUL
//-------------------------------------------------------------------
/*{Protheus.doc} GET
Retorna um json com os dados do produto consultado
@author Daniel Mendes
@since 06/07/2020
@version 1.0
*/
//-------------------------------------------------------------------
WSMETHOD GET WSRECEIVE CodProduto WSSERVICE Produtos1
local aAreaSB1 as array
Local aObjProd as array
Local aArea as array
Local cCodProd as char
Local cStatus as char
Local cJson as char
Local jObjProd
cCodProd := Self:CodProduto
aArea := GetArea()
aAreaSB1 := SB1->( GetArea() )
::SetContentType("application/json")
DbSelectArea("SB1")
SB1->( DbSetOrder(1) )
if SB1->( DbSeek( xFilial("SB1") + PadR(cCodProd,15) ) )
aObjProd := {}
cStatus := Iif( SB1->B1_MSBLQL == "1", "Sim", "Nao" )
aAdd( aObjProd, JsonObject():New() )
aObjProd[1]["Produto" ] := cCodProd
aObjProd[1]["Descricao" ] := SB1->B1_DESC
aObjProd[1]["Unidade Medida"] := SB1->B1_UM
aObjProd[1]["Status" ] := cStatus
jObjProd := JsonObject():New()
jObjProd["PRODUTOS1"] := aObjProd
cJson := jObjProd:toJson()
::setResponse(cJson)
else
setRestFault(404)
endIf
RestArea(aAreaSB1)
RestArea(aArea)
return .T.
//-------------------------------------------------------------------
/*{Protheus.doc} POST
Efetua a inserção de um produto com base no JSON recebido
@author Daniel Mendes
@since 06/07/2020
@version 1.0
*/
//-------------------------------------------------------------------
WSMETHOD POST WSSERVICE Produtos1
local jProduto
local cError as char
local cJson as char
local cAlias as char
local lOk as logical
local aAreaSB1 as array
Self:SetContentType("application/json")
jProduto := JsonObject():New()
cError := jProduto:fromJson( self:getContent() )
lOk := .F.
if Empty(cError)]
cAlias := Alias()
aAreaSB1 := SB1->( GetArea() )
if !SB1->( DbSeek( xFilial("SB1") + jProduto["CODPRODUTO"]) )
oModel := FwLoadModel("MATA010")
oModel:setOperation(MODEL_OPERATION_INSERT)
oModel:Activate()
oModel:setValue("SB1MASTER", "B1_COD", jProduto["CODPRODUTO"])
oModel:setValue("SB1MASTER", "B1_DESC", jProduto["PRODDESC"])
oModel:setValue("SB1MASTER", "B1_GRUPO", jProduto["CODGRUPO"])
oModel:setValue("SB1MASTER", "B1_TIPO", jProduto["PRODTIPO"])
oModel:setValue("SB1MASTER", "B1_UM", jProduto["PRODUM"])
oModel:setValue("SB1MASTER", "B1_LOCPAD", jProduto["PRODLOCPAD"])
oModel:setValue("SB1MASTER", "B1_ORIGEM", jProduto["PRODORIGEM"])
if oModel:VldData()
lOk := oModel:CommitData()
cJson := '{"CODPRODUTO":"' + SB1->B1_COD + '"';
+ ',"msg":"' + "Sucesso" + '"';
+'}'
::SetResponse(cJson)
else
ConErr(oModel:GetErrorMessage()[MODEL_MSGERR_MESSAGE])
SetRestFault(400)
endif
oModel:Destroy()
FreeObj(oModel)
else
SetRestFault(400, "Produto já cadastrado: " + SB1->B1_COD)
endif
RestAlias(aAreaSB1)
if !Empty(cAlias)
DBSelectArea(cAlias)
endif
else
ConErr(cError)
setRestFault(400)
endif
return lOk
//-------------------------------------------------------------------
/*{Protheus.doc} EREST_02
Função para testes do método GET da API Produtos1
@author Daniel Mendes
@since 06/07/2020
@version 1.0
*/
//-------------------------------------------------------------------
user function EREST_02()
local oRestClient as object
local aHeader as array
oRestClient := FWRest():New("http://10.21.1.24:8093")
aHeader := {"CODPRODUTO:300001"}
oRestClient:setPath("/resty/PRODUTOS1")
if oRestClient:Get(aHeader)
ConOut("GET", oRestClient:GetResult())
else
ConOut("GET", oRestClient:GetLastError())
endif
FreeObj(oRestClient)
return
//-------------------------------------------------------------------
/*{Protheus.doc} EREST_03
Função para testes do método POST da API Produtos1
@author Daniel Mendes
@since 06/07/2020
@version 1.0
*/
//-------------------------------------------------------------------
user function EREST_03()
Local aHeader as array
Local cResource as char
Local cServer as char
Local cPort as char
Local cURI as char
Local oRestClient as object
aHeader := {}
cResource := "/PRODUTOS1"
cServer := "10.21.1.24" // URL (IP) DO SERVIDOR
cPort := "8093" // PORTA DO SERVIÇO REST
cURI := "http://" + cServer + ":" + cPort + "/resty" // URI DO SERVIÇO REST
oRestClient := FwRest():New(cURI)
AAdd(aHeader, "Content-Type: application/json; charset=UTF-8")
AAdd(aHeader, "Accept: application/json")
AAdd(aHeader, "User-Agent: Chrome/65.0 (compatible; Protheus " + GetBuild() + ")")
oRestClient:setPath(cResource)
oRestClient:SetPostParams(getJson())
if oRestClient:Post(aHeader)
ConOut("POST", oRestClient:GetResult())
else
ConOut("POST", oRestClient:GetLastError())
endIf
FreeObj(oRestClient)
return
//-------------------------------------------------------------------
/*{Protheus.doc} getJson
Retorna um json (Char) para o cadastro de produtos
@return Char - Json de produto
@author Daniel Mendes
@since 06/07/2020
@version 1.0
*/
//-------------------------------------------------------------------
static Function getJson()
local jJson
jJson := JsonObject():New()
jJson["CODGRUPO"] := "001"
jJson["CODPRODUTO"] := "001323"
jJson["PRODDESC"] := "TESTE PRODUTO3 API REST"
jJson["PRODTIPO"] := "PA"
jJson["PRODUM"] := "UN"
jJson["PRODLOCPAD"] := "01"
jJson["PRODORIGEM"] := "0"
return jJson:ToJson()
O que foi feito:
- Tipagem das variáveis.
- Correção da URL do método POST.
- Remoção da abertura do ambiente no meio do método.
- Remoção da utilização da função
FWMVCRotAuto
, agora o modelo é ativo e seus valores são inseridos diretamente no mesmo, isso também gera ganho de performance. - Remoção da utilização da função
FWJsonDeserialize
, agora sempre é utilizada a JsonObject, que retorna um JSON e não um objeto.
Espero ter ajudado, desculpe por reescrever grande parte das coisas, mas acho que ficou mais fácil para exemplificar.
Rafael, por favor, edite a pergunta e anexe o código fonte.
— Daniel Mendes 06 de Jul de 2020Opa. Desculpe. Agora esta ok
— Rafael Schneider Sória 06 de Jul de 2020Agora Esta OK Daniel
— Rafael Schneider Sória 06 de Jul de 2020