Você está na página 1de 3

16/04/2021 02.

Criando uma classe REST - Frameworksp - TDN

02. Criando uma classe REST


Criado por Fabio De Moraes Rocha, última alteração por Vanessa Ruama de Sousa Barros em 24 jan, 2020
Tempo aproximado para leitura: 4 minutos
O código-fonte de uma classe REST segue o modelo de classes AdvPL e SOAP, porém os métodos são limitados aos
suportados pela implementação do protocolo no AdvPL (POST, PUT, GET e DELETE).

 Atenção
Caso uma nova classe REST seja compila após a inicialização do HTTP_START será necessário reiniciar o Application Server para que a mesma seja
publicada

Passos para criação da classe:


1. Incluir os includes TOTVS.CH e RESTFUL.CH

#INCLUDE "TOTVS.CH"
#INCLUDE "RESTFUL.CH"

Declarar a classe com o comando WSRESTFUL

WSRESTFUL sample DESCRIPTION "Exemplo de serviço REST"

 O nome declarado após o comando WSRESTFUL será utilizado no endereço (URI) para execução dos métodos (respeitando a configuração de URL do
appserver.ini), por exemplo http://localhost:8080/rest/sample

2. Declarar com o comando WSDATA as propriedades que serão utilizadas para receber os parâmetros de QueryString (opcional)

WSDATA count AS INTEGER


WSDATA startIndex AS INTEGER

3. MODO LEGADO: Declarar com o comando WSMETHOD <method> DESCRIPTION os métodos HTTP que serão utilizados (POST, PUT, GET e DELETE), não
sendo obrigatório declarar todos, somente os que serão utilizados

WSMETHOD GET DESCRIPTION "Exemplo de retorno de entidade(s)" WSSYNTAX "/sample || /sample/{id}"


WSMETHOD POST DESCRIPTION "Exemplo de inclusao de entidade" WSSYNTAX "/sample/{id}"
WSMETHOD PUT DESCRIPTION "Exemplo de alteração de entidade" WSSYNTAX "/sample/{id}"
WSMETHOD DELETE DESCRIPTION "Exemplo de exclusão de entidade" WSSYNTAX "/sample/{id}"

4. MODO RECOMENDADO: Declarar com o comando WSMETHOD <method> <id> DESCRIPTION os métodos HTTP que serão utilizados (POST, PUT, GET e
DELETE), não sendo obrigatório declarar todos, somente os que serão utilizados. A diferença em relação ao modo legado é que dessa forma é possível ter mais
que um verbo na mesma classe, por exemplo, 2 GETs 2 PUTs, desde que seja nomeado corretamente com o <id>

WSMETHOD GET ALL DESCRIPTION "Exemplo de retorno de todas as entidade(s)" PATH "/sample
WSMETHOD POST ID DESCRIPTION "Exemplo de inclusao de entidade" PATH "/sample/{id}"
WSMETHOD PUT ID DESCRIPTION "Exemplo de alteração de entidade" PATH "/sample/{id}"
WSMETHOD DELETE ID DESCRIPTION "Exemplo de exclusão de entidade" PATH "/sample/{id}"
WSMETHOD GET ID2 DESCRIPTION "Exemplo de retorno de entidade(s) sem validar empresas" PATH "/sample/{id}" NOTENANT

O NOTENANT adicionado no último método tem como função não validar empresa/filial do usuário, com ele apenas será realizada a autenticação do
mesmo. Com isso, não terá necessidade de adicionar a chave TenantId no Header da requisição.

5. Finalizar a declaração da classe com o comando END WSRESTFUL

END WSRESTFUL

6. Implementar os métodos que foram declarados com o comando WSMETHOD <method> WSSERVICE <rest>

WSMETHOD GET WSRECEIVE startIndex, count WSSERVICE sample


Local i

// define o tipo de retorno do método


::SetContentType("application/json")

// verifica se recebeu parametro pela URL


// exemplo: http://localhost:8080/sample/1
If Len(::aURLParms) > 0
// insira aqui o código para pesquisa do parametro recebido
// exemplo de retorno de um objeto JSON
::SetResponse('{"id":' + ::aURLParms[1] + ', "name":"sample"}')

https://tdn.totvs.com/display/framework/02.+Criando+uma+classe+REST 1/3
16/04/2021 02. Criando uma classe REST - Frameworksp - TDN
Else
// as propriedades da classe receberão os valores enviados por querystring
// exemplo: http://localhost:8080/sample?startIndex=1&count=10

DEFAULT ::startIndex := 1, ::count := 5

// exemplo de retorno de uma lista de objetos JSON


::SetResponse('[')

For i := ::startIndex To ::count + 1


If i > ::startIndex
::SetResponse(',')
EndIf
::SetResponse('{"id":' + Str(i) + ', "name":"sample"}')
Next
::SetResponse(']')
EndIf
Return .T.

WSMETHOD POST WSSERVICE sample


Local lPost := .T.

// Exemplo de retorno de erro


If Len(::aURLParms) == 0
SetRestFault(400, "id parameter is mandatory")
lPost := .F.
Else
// insira aqui o código para operação inserção
// exemplo de retorno de um objeto JSON
::SetResponse('{"id":' + ::aURLParms[1] + ', "name":"sample"}')
EndIf
Return lPost

Observações

Os parâmetros de QueryString devem ser declarados novamente no métodos que irão utilizados com o comando WSRECEIVE

A propriedade aURLParms contém os parâmetros de endereço (PathParam) recebido


Exemplos:
- http://localhost:8080/rest/sample/1
Valor de ::aURLParms é { "1" }
- http://localhost:8080/sample/1/test
Valor de ::aURLParms é { "1", "test" }

Os métodos devem retornar verdadeiro (.T.) em caso de sucesso no processamento ou falso (.F.) em caso de falha utilizando a função SetRestFault para
definir o código HTTP de erro para retorno

Sem rótulos

4 Comentários

https://tdn.totvs.com/display/framework/02.+Criando+uma+classe+REST 2/3
16/04/2021 02. Criando uma classe REST - Frameworksp - TDN

Daniel Fonseca De Lira


Seguem algumas informações adicionais para quem esta criando os serviços RESTful, como foram observações mediante testes, podem sofrer alterações ou
não refletir 100% do funcionamento da API:
Ao definir o WSMETHOD dentro do WSRESTFUL é bom utilizar a seguinte construção:
WSMETHOD GET id_do_servico ;
DESCRIPTION "descricao para o servico" ;
WSSYNTAX "assets/{pathparam1}/{pathparam2}" ;
PATH "assets/{pathparam1}/{pathparam2}"
É importante informa o id_do_serviço para caso existam diversas chamadas GET no mesmo objeto (isto também se aplica aos outros métodos).
É importante colocar a mesma informação do WSSYNTAX no PATH, pois é o PATH que faz a relação dos parâmetros posicionais com os atributos do
seu objeto (e não o WSSYNTAX como dá a entender).
É importante criar os atributos com o WSDATA dentro da definição do WSRESTFUL para cada parâmetro posicional informado no PATH
É útil informar o WSSYNTAX pois ele compõem a documentação do serviço mostrando os parâmetros posicionais.
Ao definir o WSDATA dentro do WSRESTFUL é bom utilizar a seguinte construção:
WSDATA pathparam1 AS type
É importante definir o type, podendo ser um dos que estão documentados em WSDATA. Esses tipos são utilizados para fazer as conversões
automaticamente, caso não seja informado todos os parâmetros serão texto, e você terá de fazer a conversão manualmente.
Ao criar o WSMETHOD fora do WSRESTFUL é bom utilizar a seguinte construção:
WSMETHOD GET id_do_servico PATHPARAM pathparam1,pathparam2 WSRECEIVE queryparam1,queryparam2 WSSERVICE classe_do_restful
É obrigatorio informar a classe_do_restful na instrução WSSERVICE
É importante informar o id_do_servico, pois podemos ter mais de um método com o verbo GET (isso também se aplica para os outros verbos)
É útil informar PATHPARAM pois ele irá facilitar a página de documentação do serviço apresentando quais são os parâmetros que serão lidos pelo
caminho da url
É útil informar WSRECEIVE pois ele irá facilitar a página de documentação do serviço apresentando quais são os parâmetros que serão lidos do
querystring
OBS: É importante observar que apontar as instruções PATHPARAM e WSRECEIVE alteram a documentação e criam variáveis locais com os nomes
dos atributos. Porem esses atributos são acessados pela classe sendo necessário utilizar a notação Self:pathparam1 ou ::pathparam1

Denis Roberto Gomes Rodrigues


@ Daniel Fonseca De Lira tudo bem?

Estava criando um serviço RESTFULL com as instruções que tu mencionou, mas de cara só informando o id do serviço o TDS já não compila e mostra
"C2003 SYNTAX ERROR ".
Essas instruções servem para a Build 12.1.17?
Obrigado

Daniel Fonseca De Lira


Olá Denis, faz um tempo que postei e que não mexo com o REST do Protheus não sei afirmar se ainda funciona da mesma forma, mas questão
de SYNTAX ERROR pode ter relação com o RESTFUL.CH, praticamente todo o processo do REST é feito em pré-processamento, então tenha
certeza que os includes estão atualizados.

Luis Angel Aboytes Rocha


¿Pudiste solucionar el error?

Política de privacidade Termos de uso

https://tdn.totvs.com/display/framework/02.+Criando+uma+classe+REST 3/3

Você também pode gostar