Pragiva — Tecnologia na prática

API REST em TLPP: o que muda em relação ao AdvPL

API REST em TLPP se escreve com annotation, e o WSRESTFUL do AdvPL ainda expõe boa parte do padrão: as duas gerações convivem. O que muda entre elas.

Protheus Guia de processo 5 min de leitura

Assista o vídeo

Resposta rápida

O que é
a mesma linguagem TLPP usada para expor um endpoint HTTP, em vez de montar uma tela MVC — a diferença central é uma annotation sobre o método, não um servidor novo.
As duas gerações
convivem. WSRESTFUL em AdvPL continua presente em boa parte do padrão; a annotation TLPP já é a forma preferida para serviço novo.
O que o TLPP acrescenta
namespace, tipagem as <Tipo> e um objeto oRest injetado no escopo, sem declaração.
Armadilha de quem vem de outra linguagem
String, Boolean, Float e Varchar não são tipos do TLPP — é Character, Logical e Numeric.
Este artigo
compara as duas gerações. Os próximos descem para a annotation, o oRest, os verbos e os erros.
Nesta página6 seções

A série sobre MVC já mostrou que o padrão continua montando tela em AdvPL, com FWFormView():New, e não migrou esse desenho para o TLPP. Em API REST a fotografia é o oposto: a TOTVS já escreve serviço novo em TLPP como prática corrente — só que sem apagar o que existia antes. Vale comparar os dois lados antes de tratar um como sucessor do outro.

As duas gerações convivem, lado a lado

WSRESTFUL, com WSMETHOD e WSDATA, ainda descreve boa parte do serviço REST escrito em AdvPL — não foi removido, nem substituído de uma vez. A annotation de verbo, em TLPP, cresce por cima disso: é a forma que a TOTVS usa para escrever API nova, não para trocar a antiga. As duas sintaxes não se misturam dentro do mesmo objeto — é a distinção que a próxima seção detalha, porque confundi-las é o erro mais fácil de cometer numa migração.

Um nome não muda o servidor, muda o acesso ao contexto

Dentro de uma classe com annotation, o acesso ao objeto de requisição é sempre oRest:, nunca ::. E o contrário nunca acontece: ::SetResponse existe, mas só em fontes que ainda usam WSRESTFUL — nenhum deles tem annotation. Não é que :: seja do modelo antigo: ele é só um apelido de Self:, sintaxe corrente de orientação a objeto no TLPP, usada em qualquer classe, com ou sem annotation. O que muda é para onde ele aponta, e o próximo artigo da série detalha isso método a método.

oRest não é declarado: não há Local oRest, Public oRest nem oRest := em nenhum controller que o usa. Ele simplesmente existe dentro do corpo do método anotado — é injetado pelo runtime do compilador, não por herança de classe.

Namespace e tipagem: o que o TLPP acrescenta de fato

Toda API nova em TLPP tende a declarar namespace, e boa parte importa outro com using namespace. Não é decoração: é como uma classe de serviço referencia uma classe de outra camada sem repetir o caminho inteiro do identificador.

A tipagem as <Tipo> é o outro acréscimo real, e ela custa uma armadilha específica para quem chega de outra linguagem. Os tipos que o TLPP reconhece de fato são Object, Character, Numeric, Array, Logical, Json e Date — não String, Boolean, Float, Varchar nem DateTime. Quem os tenta por hábito de outra linguagem não recebe um erro amigável, só um tipo que não existe.

ADVPL / TLPP
public method listar() as logical

Method listar() Class FornecedoresApi
    local jResposta := JsonObject():New() as json
    local cFiltro   := "" as character
Return .T.

Vale o aviso, porque ele engana: AS VARCHAR aparece com frequência em código real do Protheus, só que quase sempre dentro de SQL embutido em string (CAST(... AS VARCHAR( 23 ) )) ou na cláusula WSDATA de um WebService AdvPL clássico — nada disso é tipagem TLPP. O que importa é a linha de declaração de tipo de um parâmetro ou retorno, não qualquer ocorrência solta da palavra.

A tipagem do retorno de um método anotado também tem um padrão claro: as logical é, disparado, a mais comum — mais frequente do que as variant e as object somados. as json, tipando o retorno pelo formato que ele de fato devolve, é raridade. Quem tipa o retorno como o JSON que devolve está sozinho.

JsonObject mora nessa mesma família, como tipo nativo (as json), e a instanciação convive nas duas caixas — JsonObject():New() e JsonObject():new() — sem que uma seja mais correta que a outra. A linguagem é insensível a caixa, e o hábito de quem escreve não converge para uma forma só.

Os includes existem — o cabeçalho, não

Todo fonte de API em TLPP inclui tlpp-core.th e, quando expõe rota, também tlpp-rest.th. Só existe um punhado de includes tlpp-*.th na linguagem inteira, e nenhum .prw/.prx inclui algum deles — é uma fronteira real entre as duas gerações, não só de sintaxe.

try/catch existe, mas é minoria — e a grafia trai quem vem de outra linguagem

O bloco de tratamento de erro do TLPP fecha com endtry, colado, sem espaço — end try, com espaço, simplesmente não existe na linguagem. E catch não usa parênteses: é catch oError, com a variável ao lado.

ADVPL / TLPP
try
    self:runDiagnosis()
    oRest:setResponse(self:cResponseBody)
catch oError
    SetRestFault(500, FWHttpEncode(oError:description), .T.)
finally
    self:finish()
endtry

Vale considerar isso antes de vender try/catch como o jeito consolidado de tratar erro numa API: a maior parte do código real de tratamento de erro em Protheus, incluindo fonte recente, ainda resolve com o ErrorBlock() clássico do AdvPL. try/catch é o caminho certo para uma API que precisa devolver um status HTTP previsível, mas apresentá-lo como prática já consolidada seria enganar quem está aprendendo.

O que vem a seguir

Este artigo comparou as duas gerações. Os próximos descem peça por peça: a annotation e as formas reais de escrever uma rota; o objeto oRest método a método, com o que ele recebe e devolve; o primeiro @Get funcionando; como tratar erro sem devolver sempre 500; os query e path params; a paginação com FWAdapterBaseV2; o POST/PUT/DELETE gravando de verdade; e o que muda quando a API precisa responder por mais de uma empresa. Quem ainda não tem a base de MVC pode revisar antes o que é e por que ele existe.


Se sua equipe está decidindo entre manter WSRESTFUL ou migrar para annotation em TLPP, fale com a gente.

Referências

  1. TDNtdn.totvs.com

    TDN — Migração WsRESTful para REST tlppCoreTDN devolve 403 sem login na consulta direta.
  2. TDNtdn.totvs.com

    TDN — REST (TOTVSTEC)
  3. TDNtdn.totvs.com

    TDN — Entendendo as novidades do RESTIndicada pelo catálogo como visão geral da annotation.

Continue por aqui