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).
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"
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
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}"
Finalizar a declaração da classe com o comando 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 |
1 Comment
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