Pular para o conteúdo

Referencie valores entre blocos

A sintaxe {{...}} é o que transforma o httui de “um editor markdown” em “um runtime encadeado”. Esse guia é o cheatsheet completo de referências: de onde vêm, pra onde podem ir, que regras de escopo se aplicam.

{{ alias . campo . path }}
^^^^^ ^^^^^ ^^^^
| | |
| | JSON path dentro do campo
| body | status | headers | cookies | row
alias do bloco cuja response você quer

Espaço em branco dentro de {{ ... }} é permitido mas desencorajado pra grep-ability.

CampoO que éExemplo
bodyBody da response JSON-parseado (ou texto se não for JSON){{login.body.token}}
statusStatus code HTTP numérico{{login.status}}
headers.<name>Valor de header de response{{login.headers.x-request-id}}
cookies.<name>Valor de set-cookie{{login.cookies.session}}
sizeTamanho do body em bytes{{download.size}}
timeTempo total em ms{{slow.time}}

Blocos DB têm um campo extra:

CampoO que éExemplo
row[N]n-ésima linha do result set{{users_list.row[0].email}}
rowsArray completo de linhas{{users_list.rows}} (raro)
affectedLinhas afetadas por INSERT/UPDATE/DELETE{{seed.affected}}

Depois de body. você pode navegar em qualquer formato JSON com notação ponto e indexação [N]:

```http alias=order
GET {{BASE_URL}}/orders/{{previous.body.data.items[0].id}}
Authorization: Bearer {{login.body.tokens.access_token}}
```
Pattern
body.user.id{ user: { id: 42 } }42
body.items[0].name{ items: [{ name: "x" }] }"x"
body.tags[2]{ tags: ["a", "b", "c"] }"c"
body.nested["odd key"]bracket-quoted pra keys que não são identifier
body[*].nameNÃO suportado — use blocos encadeados ou expects

Quando você não liga pro nome, $prev é “o bloco anteriormente executado, response como raiz implícita”:

```http alias=login
POST {{BASE_URL}}/auth/login
```
```http
GET {{BASE_URL}}/users/{{$prev.body.user.id}}
```

{{$prev.body.user.id}} é exatamente {{login.body.user.id}}. Use quando o alias é óbvio pelo contexto (estilo script de uma só execução).

Referências resolvem nessas posições antes do bloco despachar:

Tipo de blocoPosiçãoExemplo
HTTPURLGET {{BASE_URL}}/x
HTTPkey de header{{HEADER_NAME}}: value
HTTPvalue de headerAuthorization: Bearer {{token}}
HTTPbody (qualquer content type){ "id": {{user.body.id}} }
HTTPquery string?since={{cutoff.body.iso}}
DBtexto SQLSELECT * FROM x WHERE id = {{user.body.id}}
DBparams da conexão (host/port via session override){{PG_HOST}}
Standalonebody do blocodepende do tipo de bloco

Referências não resolvem em tokens da info-string (alias=..., timeout=...) — esses são configuração, não dados.

Quando um {{...}} aparece num bloco SQL, o httui não faz string-interpolation. A referência vira um bind parameter ($1 pra Postgres, ? pra SQLite/MySQL), e o valor resolvido passa pelo prepared-statement binding do driver:

```db-local
SELECT * FROM orders
WHERE customer_id = {{user.body.id}}
AND created_at &gt; {{cutoff.body.iso}}
```

O que o driver vê:

SELECT * FROM orders
WHERE customer_id = $1
AND created_at > $2

Valores de bind: [user.body.id, cutoff.body.iso].

Zero superfície de SQL injection, mesmo com valores controlados pelo usuário vindo via responses HTTP.

Se você tem um bloco com alias BASE_URL e uma env var também chamada BASE_URL, o bloco vence quando os dois estão em escopo:

```http alias=BASE_URL
GET https://dynamic-discovery.example.com/url
```
```http
GET {{BASE_URL}}/health # usa o body da response do bloco como URL!
```

Isso é by design (dá aos runbooks uma forma de sobrescrever valores de env em runtime), mas é fácil se surpreender. Regra de ouro: use ALL_CAPS pra env vars, snake_case ou kebab-case pra aliases de bloco.

Quando você roda um bloco que referencia {{other.body.X}}, o httui:

  1. Faz parse das referências no seu bloco.
  2. Acha que other é um alias definido acima do bloco atual.
  3. Checa o cache — se o hash dos inputs de other (body, env, refs) bate com a run cacheada, usa a response cacheada.
  4. Senão roda other (que pode disparar dependências upstream — recurse).
  5. Substitui o valor resolvido no seu bloco.
  6. Roda seu bloco.

Referências só podem apontar pra cima no arquivo. Isso faz do runbook uma DAG por construção — sem ciclos possíveis, sem loops “bloco 3 referencia bloco 7 que referencia bloco 2”.

CausaO que você vê
Alias não existe em nenhum bloco acimaEditor sublinha a ref em vermelho; hover mostra “unknown alias”
Path do field não existe na responseBloco roda, painel mostra erro: “path body.user.id not found in response”
Bloco upstream ainda não rodouO httui roda primeiro (auto-exec)
Bloco upstream deu erroO erro propaga — bloco downstream não roda, painel mostra “upstream login failed”
OndeComo
No editorHover no {{...}} — popup mostra valor resolvido ou erro
Antes da runO popup atualiza ao vivo conforme o cache enche
Depois da runAba Raw do painel de response mostra a request literal, todas as refs já substituídas
No drawerClique no da toolbar do bloco → aba References lista cada ref com o valor atual