Olá, boa tarde.
Estou aprendendo TLPP aqui e estou tentando jogar um JSON de uma Service para a minha Controller.
Eu fiz da seguinte forma, primeiro, defini a Controller que criou a API com sucesso, e está recebendo os argumentos do REQUEST como deveria (Tirei partes que acho que não é necessário p/ entendimento):
Method get() as Logical Class SolicitacaoArmazemController
// Setar Empresa e Filial no começo do App (Necessário)
rpcSetEnv(cEmpAnt, cFilAnt)
ConOut("SolicitacaoArmazemController:get - Coletando os Parametros da Query e do JSON Body")
// Etc
// Simular o jResponse (O JSON que tem na Classe) pra simular a resposta.
// Inicialmente, trago da Service para testes e entendimento da arquitetura.
Local cResponseJson as Json
// Etc
// Retornar um JSON criado pela Service
cResponseJson := SolicitacaoArmazem:get()
cTesteChegouAqui := "Sim ou não?"
ConOut("SolicitacaoArmazemController:get - Configurando os Headers e a Response")
oRest:setKeyHeaderResponse('Content-Type', 'application/json; charset=utf-8')
oRest:setResponse(cResponseJson)
// Resetar a Empresa/Filial e liberar licenças utilizadas.
rpcClearEnv()
Return .T.
E ai na minha Service
eu crio um JSON pra testes, que eu passo para a minha Controller
:
class SolicitacaoArmazemService
Public Data jResponse as Json
Public method new() as Object
Public method get() as Json
EndClass
Method new() as Object Class SolicitacaoArmazemService
ConOut("SolicitacaoArmazemService:new - Construindo a Service e instanciando JsonObject...")
::jResponse := JsonObject():New()
Return Self
Method get() as Json Class SolicitacaoArmazemService
Local jResponse := '[{"Mensagem":"Hello World!"}]'
Return ::jResponse
Porém, ele não vai pra frente na linha cResponseJson := SolicitacaoArmazem:get()
.
Informações adicionais:
No Debug, ele quando chega na linha em questão tem o cResponseJson
definido como Nil
, e na linha seguinte ele para de executar e não preenche o cTesteChegouAqui
. Vejam a imagem:
Atenção: Esta publicação foi transferida automaticamente do fórum antigo, mas os anexos não foram incluídos.
1 curtida
Raul,
Seu código tem alguns problemas:
Você está abrindo o ambiente para cada requisição? Isso vai gerar uma lentidão IMENSA na sua API e seria impossível manter isso de pé em produção caso seja uma API muito utilizada:
rpcSetEnv(cEmpAnt, cFilAnt)
A primeira coisa que deve ser feita em ADVPL/TLPP é declarar as variáveis, então fico na dúvida, isso está compilando? Pois você declara a variável após abrir o ambiente e fazer um conout:
Local cResponseJson as Json
Quando um método da classe é chamado a primeira vez, ele cria uma instancia da classe, por padrão, damos o nome de new a esse método, mas isso não é uma regra, qualquer método da classe ao ser invocado pela primeira vez é o construtor, logo esse código, está devolvendo um objeto:
cResponseJson := SolicitacaoArmazem:get()
Na classe SolicitacaoArmazem, método get, você coloca um valor de character na variável jResponde e não faz nada com ele, você acaba retornando a propriedade jResponse da classe, que pode estar nulo ou com um JSON vazio:
Local jResponse := '[{"Mensagem":"Hello World!"}]'
Return ::jResponse
Obs.: Para chamar um método sem instanciar a classe, você precisa declarar o método como estático, mas isso muda o comportamento, ele passa a ser um método da classe e não do objeto.
Para corrigir essa situação, poderia ser feito algo nessa linha de raciocínio:
Controller:
Method get() as Logical Class SolicitacaoArmazemController
Local jResponseJson as Json
Local oService as object
//TODO: Precisa mesmo abrir o ambiente, ainda mais com as variáveis públicas cEmpAnt e cFilAnt? Não acaba ficando exatamente a mesma coisa? Veja mais na configuração do REST para já deixar o ambiente aberto e evitar isso
rpcSetEnv(cEmpAnt, cFilAnt)
ConOut("SolicitacaoArmazemController:get - Coletando os Parametros da Query e do JSON Body")
oService := SolicitacaoArmazem():new()
jResponseJson := oService:get()
cTesteChegouAqui := "Sim ou não?"
ConOut("SolicitacaoArmazemController:get - Configurando os Headers e a Response")
oRest:setKeyHeaderResponse('Content-Type', 'application/json; charset=utf-8')
oRest:setResponse(jResponseJson)
//TODO: Se remover o RpcSetEnv, remover essa chamada também
rpcClearEnv()
Return .T.
Service:
class SolicitacaoArmazemService
Public Data jResponse as Json
Public method new() as Object
Public method get() as Json
EndClass
Method new() as Object Class SolicitacaoArmazemService
ConOut("SolicitacaoArmazemService:new - Construindo a Service e instanciando JsonObject...")
::jResponse := JsonObject():New()
Return Self
Method get() as Json Class SolicitacaoArmazemService
::jResponse:fromJson('[{"Mensagem":"Hello World!"}]')
Return ::jResponse
Show. Obrigado Daniel, fez sentido agora! Eu não estava entendendo a lógica ali de como funcionava a parte de instanciar a classe e como eu fazia isso no método GET ali da classe… Sobre o ambiente da empresa, obrigado. Eu não sabia disso, vou configurar no AppServer lá pra sempre deixar aberto já na empresa certa. Testei aqui e deu certinho. Thanks!