REST no Protheus — Básico do básico
REST… Que diabos é isso?
Bem, REST é o acrônimo de Representational State Transfer… E continuamos sem saber o que é… Resumindo, é uma forma de enviar e receber dados utilizando do protocolo HTTP. Explanar sobre o que é o REST/RESTful é complexo e existem diversas documentações sobre. Vou deixar essas aqui para quem estiver interessado em conhecer mais sobre o conceito:
A LIB do Protheus já vem pronta para rodar um servidor HTTP, recebendo e respondendo requisições REST.
Então, é só subir o server (appserver) e pronto? Não!! É necessário habilitar esse servidor nas opções do appserver.ini. Com isso, um job ficará em execução, escutando a porta designada nas configurações. A seguir, um exemplo de como as configurações podem ser feitas:
Com isso, temos um servidor http escutando na porta 8080, sendo que a base de resposta sempre será /rest. Por exemplo, http://localhost:8080/rest/minha_api
Legal, temos um server. E agora? Agora vem a parte legal, a parte de criar a sua classe, seu endpoint!
A classe REST no Protheus precisa ser criada seguindo uma estrutura diferente de uma classe tradicional, pois ela, após a pré-compilação, acaba herdando de uma classe que já existe na LIB do Protheus.
Criando a classe:
Vamos declarar a classe, sendo que na declaração dela, já vamos criar um GET para teste. Veja que na declaração do método, já especificamos a URL que esse método vai responder:
Criando um método:
Agora vamos criar um GET simples, que vai retornar um bagulho insano! Vai retornar um Hello World:
Consumindo a API:
Vamos ver nosso Hello World, consumindo nosso método no endereço http://localhost:8080/rest/dnlrestetc/v1/, que é a soma da configuração do REST no appserver.ini e da URL que foi especificada na declaração do método:
Isso é o básico… Agora, vamos alterar essa mesma classe para persistir um JSON no database, efetuar um CRUD básico.
Vamos começar por algumas funções que vão nos ajudar a implementar os verbos na classe, pois diversos métodos vão utilizar de funções muito similares, vamos fazer nosso CRUD no SQLite, banco que já vem pronto para uso no Appserver:
Vamos explicar cada uma dessas funções em ordem:
- existID — Verifica se o ID (nossa “PK”) já existe no SQLite
- addJson — Adiciona o JSON recebido na requisição no SQLite
- getJson — Retorna o JSON já persistido no SQLite
- updateJson — Atualiza o JSON já persistido no SQLite
- deleteJson — Apaga o JSON já persistido no SQLite
- createTable — Cria a tabela que será utilizada pela class REST
- existTable — Indica se a tabela da class REST já existe no SQLite
Obs.: Temos algumas constantes para evitar sempre escrever o mesmo nome da tabela com a possibilidade de errar, poderia também ser uma função; Também temos uma variável estática, para evitar que toda vez seja verificada a existência da tabela. Isso é apenas uma questão para ganho de performance.
Redeclaração da classe:
Vamos atualizar a declaração de nossa classe, pois vamos ter novos métodos e dizer adeus ao amado Hello World:
Essa propriedade idJSON, será nossa “PK”. Com ela, vamos gerar um ID único para cada JSON. Ela será usada na URL e a LIB do Protheus vai preenchê-la por baixo dos panos.
Vamos aos métodos:
- POST:
Criando o POST, para termos algo inicial:
Consumindo o POST, enviando um JSON qualquer, temos o seguinte cenário:
Veja que foi retornado um ID. Esse cara é a nossa “PK”, que será utilizado para retornar esse mesmo JSON. Persistido e seu valor, ficará presente na propriedade idJSON da classe!
- GET:
Legal, como já temos o POST, vamos incluir um JSON com ele e efetuar o GET do mesmo. Bora implementar o GET:
Com o GET implementado, vamos consumir o JSON que anteriormente persistimos:
- PUT:
E se eu precisar atualizar o meu JSON? Bora implementar o PUT:
Agora, vou atualizar o JSON, criando inclusive novos dados:
- DELETE:
Agora só falta… A exclusão do JSON, né:
Vamos deletar nosso JSON com aqueles dados super importantes:
Na dúvida da deleção, vamos consultar se ele ainda existe com o GET:
Observações:
Para facilitar a implementação e testes, utilizei o SQLite que já vem no Appserver. Porém, você pode utilizar um banco tradicional, conectar no DBAccess e ser feliz!
O Appserver trabalha no máximo com variáveis de 1MB. Portanto, é de grande importância verificar o MaxStringSize no appserver.ini.
Conclusão?
O Protheus já possui uma LIB pronta para a criação de endpoints, conforme sua necessidade, sendo que diversas APIs já vêm prontas para uso. Atualmente, elas estão sendo documentadas no endereço abaixo:
Vou deixar alguns links sobre o REST no Protheus e também sobre HTTP em geral, códigos de retorno etc:
Aqui um outro exemplo de REST no Protheus que utilizo bastante quando quero fazer testes. Sim, é meu:
Por fim, temos aqui um artigo criado por um amigo meu, bem bacana, com uma implementação bem mais arrojada: