Pular para o conteúdo

Adicione um banco de dados no seu runbook

Esse tutorial te guia conectando seu primeiro banco no httui e misturando blocos SQL com blocos HTTP no mesmo runbook — o fluxo que transforma “verifica se staging bate com o DB” numa tarefa de 30 segundos em vez de três ferramentas e um shell.

Vamos usar SQLite pra você não precisar instalar Postgres nem rodar docker — o httui cria o arquivo .sqlite na primeira run.

Tempo: ~15 minutos · Pré-requisitos: terminou o Quickstart.

No sidebar, clique no ícone de banco (Connections). No painel da direita:

  1. Clique em + Add connection.
  2. Escolha SQLite no dropdown Type.
  3. Name: local — curtinho, isso vira parte do nome do fence do bloco.
  4. Path: ./scratch.sqlite (relativo à raiz do seu vault).
  5. Clique em Save.

Isso escreve um bloco no connections.toml:

[connections.local]
type = "sqlite"
path = "./scratch.sqlite"

Crie runbooks/users-check.md. Adicione um título curto e intro:

# Sanity check de users
SQLite local pra imitar a tabela de users que vamos consultar em
staging.

Depois adicione um bloco DB (o fence é db-<connection-name>):

```db-local
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT,
created_at INTEGER DEFAULT (unixepoch())
);
INSERT INTO users (name, email)
VALUES
('Alice', 'alice@example.com'),
('Bob', 'bob@example.com'),
('Charlie', 'charlie@example.com')
ON CONFLICT DO NOTHING;
```

O fence é db-local — isso é db- + o nome da conexão do passo 1. Cada conexão auto-registra seu próprio tipo de bloco.

Aperte Cmd+Enter no bloco. Você vai ver um banner primeiro:

⚠ Esse bloco contém INSERT. Rodar mesmo assim?

Esse é o mutation guard — o scanner SQL do httui flagueou uma statement destrutiva e tá perguntando antes de deixar você reescrever produção sem querer. Clique em Run once. O bloco roda e você vê “3 rows affected”.

Adicione um bloco SELECT:

```db-local alias=users_list
SELECT id, name, email, created_at
FROM users
ORDER BY id
```

Aperte Cmd+Enter. A response é uma grid virtualizada — colunas ordenáveis, badge de tipo por coluna, botão copy-as-CSV. Teste o sort no header da coluna e repare que é instantâneo mesmo em 100k linhas (a grid é janelada).

O alias=users_list importa pro próximo passo.

Agora a mágica: use uma linha SQL como input pra um bloco HTTP. Adicione:

```http alias=user_detail
GET https://httpbin.org/anything/users/{{users_list.row[0].id}}
Accept: application/json
# expect:
# status == 200
# body.url contains "/users/1"
```

O que {{users_list.row[0].id}} faz:

ParteSignifica
users_listo alias do bloco SQL acima
row[0]primeira linha do result set
.idcoluna id daquela linha

Aperte Cmd+Enter em user_detail. O httui:

  1. Vê a referência → roda users_list primeiro (já cacheado → instantâneo).
  2. Substitui 1 por {{users_list.row[0].id}} → a URL vira .../users/1.
  3. Manda a request e faz assert da response.

Você acabou de encadear uma query SQL numa request HTTP real. O mesmo pattern funciona ao contrário — use um valor de response HTTP como parâmetro SQL:

```db-local
SELECT * FROM users WHERE id = {{user_detail.body.json.id}}
```

Adicione mais um bloco:

```db-local
EXPLAIN QUERY PLAN
SELECT * FROM users WHERE id = 1
```

Aperte Cmd+Enter. SQLite retorna o plano; pra Postgres / MySQL o mesmo bloco nesses drivers renderiza o EXPLAIN ANALYZE como tree view com scans sequenciais lentos destacados em vermelho. Botão-direito em qualquer nó pra “Copy as TEXT”.

Seu runbook agora tem o loop:

graph LR
A[users_list - SQL] -- row[0].id --> B[user_detail - HTTP]
B -- assert --> C[passa/falha]

Commite. Abra o mesmo vault amanhã, aperte Run all e você vai saber em 500ms se o DB e a API ainda concordam.