Api com autenticação sem codificar
Esse post foi retirado do repositório https://github.com/alisonjr/pg-rest
Recentemente conheci uma ferramenta incrível escrita em Golang que possibilita ter uma API do estilo "data driven" de forma rápida e extremamente fácil e com zero linhas de código. Sendo assim uma ótima opção para quando há necessidade de uma prototipação rápida, ou construir uma POC com pouco esforço na parte de backend.
No exemplo desse artigo será criado uma base de dados nova. Mas o que é demonstrado aqui pode facilmente ser aplicado a um banco de dados postgres já existente. Basta configurar as credenciais de conexão com o banco nas variáveis de ambiente do container do pRest.
Para executar o exemplo será necessário criar um arquivo docker-compose.yml
com dois serviços: Um banco de dados Postgres e a grande estrela: pRest 🤩🤩.
O pRest é uma ferramenta escrita em Go e adiciona uma camada rest em cima do banco de dados. Para mais informações acesse https://prestd.com.
para baixar o docker-compose.yml acesse https://github.com/alisonjr/pg-rest/blob/main/docker-compose.yml
O pRest transforma seu banco de dados Postgres em um serviço Rest instantaneamente, com autenticação, JWT e sem a necessidade de escrever uma linha de código. 🤩🤩
Para entender como funciona as operações de 'CRUD' consulte https://docs.prestd.com/prestd/docs/api-reference/. Já aviso que a API rest do pRest é bastante poderosa, posibilitando fazer queries mais complexas inclusive com joins e muito mais, consulte https://docs.prestd.com/prestd/docs/api-reference/advanced-queries/
Como fazer
Requisitos
- Ter o Docker instalado
- Ter o Docker Compose instalado
Mão na massa
configuração
Abra um terminal na pasta em que você salvou o arquivo docker-compose.yml e digite:
docker-compose up
Um banco novo do postgres foi criado e está disponível para utilizarmos.
Como indicamos para o pRest que iremos trabalhar com uma API com autenticação (indicado no docker-compose.yml
em PREST_AUTH_ENABLED=true
) e como também nosso banco de dados é novo e não possui nenhuma tabela ainda, é necessário que uma estrutura mínima de autenticação seja criada. E o pRest tem um comando para isso. Abra outro terminal e digite:
docker-compose exec prest prestd migrate up auth
Agora com a estrutura criada, podemos criar um usuário para poder utilizar a API.
Vamos criar usuário com o nome 'pREST Full Name', username 'prest' e a senha também será 'prest'
docker-compose exec postgres psql -d prest -U prest -c "INSERT INTO prest_users (name, username, password) VALUES ('pREST Full Name', 'prest', MD5('prest'))"
Você pode verificar se o usuário realmente foi criado com um select simples
docker-compose exec postgres psql -d prest -U prest -c "select * from prest_users"
A saída deve ser algo parecido com isso
id | name | username | password | metadata
----+-----------------+----------+----------------------------------+----------
1 | pREST Full Name | prest | 8c60e97b9cf709c643e4a583b1ae9cb1 |
(1 row)
E PRONTO!!!🤩🤩 Uma API segura em frente ao seu banco de dados, e agora pode consumi-lo por http, sem precisar de conectores ou escrever sql.
Autenticar
Você pode enviar as credenciais como json para o endpoint /auth
. Você pode utilizar qualquer cliente http, como postman, insonmia e etc, ou o bom e velho curl:
curl -i -X POST http://127.0.0.1:3000/auth -H "Content-Type: application/json" -d '{"username": "prest", "password": "prest"}'
O retorno deve ser algo parecido com isso
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 02 Mar 2023 01:43:53 GMT
Content-Length: 329
{"user_info":{"id":1,"name":"pREST Full Name","username":"prest","metadata":null},"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySW5mbyI6eyJpZCI6MSwibWV0YWRhdGEiOm51bGwsIm5hbWUiOiJwUkVTVCBGdWxsIE5hbWUiLCJ1c2VybmFtZSI6InByZXN0In0sImV4cCI6MTY3Nzc0MzAzMywibmJmIjoxNjc3NzQzMDMzfQ.wVKffo6oSuMiFj8JgQD6nXGQ1n-Xgj-zdXrH7zhGtBM"}
Onde o que nos interessa aqui é o conteúdo da resposta
{
"user_info":{
"id":1,
"name":"pREST Full Name",
"username":"prest",
"metadata":null
},
"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySW5mbyI6eyJpZCI6MSwibWV0YWRhdGEiOm51bGwsIm5hbWUiOiJwUkVTVCBGdWxsIE5hbWUiLCJ1c2VybmFtZSI6InByZXN0In0sImV4cCI6MTY3Nzc0MzAzMywibmJmIjoxNjc3NzQzMDMzfQ.wVKffo6oSuMiFj8JgQD6nXGQ1n-Xgj-zdXrH7zhGtBM"
}
O token recebido deve ser utilizado em todas as requisições a serem feitas para a API!
Criar uma tabela
Para simplificação vamos criar uma tabela nova diretamente no banco de dados
docker-compose exec postgres psql -d prest -U prest -c "create table books (id serial PRIMARY KEY,title varchar(255),author varchar(255), pages integer,quantity integer)"
Utilizando o pRest
A estrutura de path do pRest é bem simples sendo /{database}/{schema}/{table}
Filtros também são possíveis através de query params, como por exemplo:
curl -i -X GET http://127.0.0.1:3000/prest/public/books?id=1 -H "Accept: application/json" -H "Authorization: Bearer {token}"
Vamos enviar um novo registro para a nossa api
curl -i -X POST http://127.0.0.1:3000/prest/public/books -H "Accept: application/json" -H "Authorization: Bearer {token}" -d '{"title": "Dune", "author": "Frank Herbert", "pages":680, "quantity":100}'
O retorno será algo parecido com isso
HTTP/1.1 201 Created
Content-Type: application/json
Date: Thu, 02 Mar 2023 02:01:10 GMT
Content-Length: 75
{"id":1,"title":"Dune","author":"Frank Herbert","pages":680,"quantity":100}
Fazendo consultas na tabela books como select * from books where title like %title%
curl "http://127.0.0.1:3000/prest/public/books?title:tsquery=dune" -H 'Accept: application/json' -H 'Authorization: Bearer {token}'
Atualizar um registro
curl -i -X PUT http://127.0.0.1:3000/prest/public/books?id=1 -H "Accept: application/json" -H "Authorization: Bearer {token}" -d '{"title": "updated title", "author": "updated author"}'
O retorno será algo parecido com isso
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 02 Mar 2023 02:04:32 GMT
Content-Length: 19
{"rows_affected":1}
Remover um registro
curl -i -X DELETE http://127.0.0.1:3000/prest/public/books?id=1 -H "Accept: application/json" -H "Authorization: Bearer {token}"
Retorno
HTTP/1.1 200 OK
Content-Type: application/json
Date: Thu, 02 Mar 2023 02:17:14 GMT
Content-Length: 19
{"rows_affected":1}
Bom pessoal, esse é o básico! Para mais operações consulte a documentação oficial do pRest https://docs.prestd.com/