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
Passos para criação da classe:
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/sampleDeclarar 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
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}"
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.
Finalizar a declaração da classe com o comando END WSRESTFUL
END WSRESTFUL
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"}') 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
4 Comentários
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:
É 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:
Ao criar o WSMETHOD fora do WSRESTFUL é bom utilizar a seguinte construção:
É 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
Usuário desconhecido (denis.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?