Pular para o conteúdo

Respostas

respond, status, cabeçalhos, cookies e arquivos.

As formas de `respond`#

dataforge
respond json {"ok": yes}              // 200, application/json
respond html "<h1>Oi</h1>"           // 200, text/html
respond text "pong"                  // 200, text/plain
respond file "/tmp/relatorio.xlsx"   // com o Content-Type do arquivo

respond 201 json novo                // status antes do tipo
respond 404 json {"erro": "não achei"}
respond 204                          // só status, sem corpo

respond {"a": 1}                     // sem tipo: vault vira JSON
respond "<p>oi</p>"                  // texto começando com '<' vira HTML

Um inteiro logo depois de respond é sempre o status. Para responder o número 404 como JSON, escreva respond json 404.

`respond` encerra a rota#

dataforge
route GET "/":
    respond json {"ok": yes}
    out "isto nunca roda"

Exatamente como yield encerra uma ação. É o que permite escrever guardas sem otherwise:

dataforge
route GET "/itens/:id":
    p := achar(params["id"])
    given p is void:
        respond 404 json {"erro": "não achei"}
    respond json p

Os status que importam#

CódigoQuandoCorpo
200deu certoo recurso
201criou algo novoo que foi criado
204deu certo, nada a dizernenhum
302mudou de lugar por oravazio, Location no cabeçalho
400o cliente mandou dado inválidoo que está errado
401não sei quem é vocêcomo se autenticar
403sei quem é você, e não podepor quê
404não existeopcional
409conflito (já existe, versão velha)o conflito
422entendi o formato, mas o dado não serveos campos
429pedidos demaisRetry-After
500o servidor quebrounada de detalhe em produção

Devolver 200 com {"erro": …} no corpo obriga todo cliente a inspecionar o JSON para saber se deu certo. O código HTTP existe para isso.

Cabeçalhos e cookies#

dataforge
pronto := Kiln.json({"ok": yes})
Kiln.header(pronto, "X-Versao", "4.2")
Kiln.cookie(pronto, "tema", "escuro", 30)     // 30 dias
respond pronto

Kiln.cookie já marca HttpOnly e SameSite=Lax — os dois padrões que fecham a maioria dos problemas. Passe seguro: yes para exigir HTTPS, e dias: 0 para apagar o cookie.

Redirecionar#

dataforge
route GET "/antigo":
    redirect "/novo"                 // 302, temporário

route GET "/mudou-de-vez":
    redirect "/novo" status 301      // permanente

O 301 fica no cache do navegador praticamente para sempre. Use só quando o endereço mudou de verdade — voltar atrás depois é muito trabalho.

Servir um arquivo#

dataforge
route GET "/relatorio.xlsx":
    // gerado na hora, com os dados de agora
    livro := montar_planilha()
    Xls.save(livro, "/tmp/r.xlsx")
    respond file "/tmp/r.xlsx"

// forçando o download com um nome
respond Kiln.file("/tmp/r.xlsx", void, "relatorio-marco.xlsx")

Páginas de erro#

dataforge
Kiln.on_error(app, 404, lambda req => Kiln.html(
    "<h1>404</h1><p>Não achei essa página.</p>", 404))

Kiln.on_error(app, 500, lambda req => Kiln.html(
    "<h1>Algo quebrou</h1><p>Já estamos olhando.</p>", 500))

Mantenha o status. Uma página de erro que responde 200 é indexada pelos buscadores como se fosse conteúdo.