DEV Community

Cover image for Postgres as Rest
Alison Rodrigues
Alison Rodrigues

Posted on

Postgres as Rest

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.

version: "3"
services:
  postgres:
    image: postgres
    volumes:
      - "./data/postgres:/var/lib/postgresql/data"
    environment:
      - POSTGRES_USER=prest
      - POSTGRES_DB=prest
      - POSTGRES_PASSWORD=prest
    ports:
      - "5432:5432"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready", "-U", "prest",  "-d", "prest"]
      interval: 30s
      retries: 3
  prest:
    image: prest/prest:v1.1
    links:
      - "postgres:postgres"
    environment:
      - PREST_DEBUG=false
      - PREST_AUTH_ENABLED=true
      - PREST_PG_HOST=postgres
      - PREST_PG_USER=prest
      - PREST_PG_PASS=prest
      - PREST_PG_DATABASE=prest
      - PREST_PG_PORT=5432
      - PREST_SSL_MODE=disable
      - PREST_CACHE_ENABLED=false
      - PREST_CACHE=false
    depends_on:
      postgres:
        condition: service_healthy
    ports:
      - "3000:3000"
Enter fullscreen mode Exit fullscreen mode

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

Os exemplos a seguir foram retirados da documentação oficial do pRest https://docs.prestd.com/prestd/docs/setup/docker/#with-docker-compose

e de um artigo do Elton Minetto https://eltonminetto.dev/en/post/2021-08-31-prest

Requisitos

  • Ter o Docker instalado
  • Ter o Docker Compose instalado

Mão na massa

configuração

Abra um terminal na pasta em que está o arquivo docker-compose.yml e digite:

docker-compose up
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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'))"
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

A saída deve ser algo parecido com isso

 id |      name       | username |             password             | metadata
----+-----------------+----------+----------------------------------+----------
  1 | pREST Full Name | prest    | 8c60e97b9cf709c643e4a583b1ae9cb1 |
(1 row)
Enter fullscreen mode Exit fullscreen mode

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"}'
Enter fullscreen mode Exit fullscreen mode

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"}
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

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)"
Enter fullscreen mode Exit fullscreen mode

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}"
Enter fullscreen mode Exit fullscreen mode

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}'
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

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}'
Enter fullscreen mode Exit fullscreen mode

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"}'
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

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}"
Enter fullscreen mode Exit fullscreen mode

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}
Enter fullscreen mode Exit fullscreen mode

Bom pessoal, esse é o básico! Para mais operações consulte a documentação oficial do pRest https://docs.prestd.com/

Top comments (0)