Pular para o conteúdo

Rotas e parâmetros

Padrões de caminho, query string, corpo e os seis atalhos que toda rota recebe.

Os verbos#

dataforge
server api on 8080:
    route GET "/itens":
        respond json itens

    route POST "/itens":
        respond 201 json body

    route PUT "/itens/:id":
        respond json trocado

    route DELETE "/itens/:id":
        respond 204

    route HEAD "/saude":
        respond 200

    route ANY "/webhook":
        respond 200

O corpo da rota é um bloco indentado, como o de uma ação — não cabe na mesma linha do route.

ANY casa qualquer verbo — útil para webhooks de serviços que mudam de método sem avisar.

Padrões de caminho#

PadrãoCasaNão casaResultado
/itens/itens, /itens//itensX{}
/itens/:id/itens/42/itens{"id": "42"}
/u/:id/posts/:post/u/7/posts/3/u/7dois parâmetros
/files/*caminho/files/a/b.txt{"caminho": "a/b.txt"}

:nome casa um trecho; *nome casa tudo o que sobrar, barras inclusive. Um parâmetro chega já decodificado: /b/ma%C3%A7%C3%A3"maçã".

Os seis atalhos#

Dentro de uma rota, seis nomes já existem:

dataforge
route POST "/itens/:id":
    out params["id"]        // do caminho
    out query["formato"]    // da query string
    out body["nome"]        // o corpo, já interpretado
    out headers["authorization"]
    out session["usuario"]
    out req["method"], req["ip"]    // e a requisição inteira
NomeÉQuando falta a chave
paramsparâmetros do caminhonão falta — o padrão garante
querya query stringerro — use ??
bodyo corpo interpretadoerro — use ??
headerscabeçalhos, em minúsculaserro — use ??
sessiona sessão do visitanteerro — use ??
reqtudo, mais method, path, ip, state

A armadilha do `??`#

query, body e headers vêm de fora: a chave pode simplesmente não vir. Indexar um vault sem a chave é erro, e dentro de uma rota isso vira 500.

dataforge
// 500 na primeira visita sem filtro
route GET "/":
    respond json listar(query["categoria"])

// certo
route GET "/":
    respond json listar(query["categoria"] ?? void)

Esta é a causa número um de 500 inesperado em código Kiln novo. params é a exceção: se a rota casou, o parâmetro existe.

Query com um valor e com vários#

?nome=x"x"; ?tag=a&tag=b["a", "b"]. Obrigar a indexar [0] sempre seria ruído em 95% dos casos — mas vale lembrar disso ao ler um campo que pode repetir.

O corpo, por Content-Type#

Content-Typebody é
application/jsonvault ou cluster — ou o texto cru, se o JSON estiver quebrado
application/x-www-form-urlencodedvault (formulário HTML)
qualquer outroo texto
sem corpovoid

JSON inválido não vira 500. Chega como texto, e a rota decide — porque JSON quebrado é problema do cliente, e a resposta certa é 400, não "o servidor caiu".

404 e 405#

dataforge
// só GET e POST registrados em /itens
Kiln.test(api, "GET",    "/itens")   // 200
Kiln.test(api, "DELETE", "/itens")   // 405, Allow: GET, POST
Kiln.test(api, "GET",    "/nada")    // 404

O 405 traz Allow com os verbos aceitos. Devolver 404 ali mandaria o cliente procurar um caminho que existe.

Agrupar rotas#

dataforge
server admin on 0:
    route GET "/usuarios":
        respond json usuarios

server api on 8080:
    route GET "/saude":
        respond 200

// as rotas do admin passam a viver sob /admin
Kiln.mount(api, "/admin", admin)

mount copia as rotas do outro server com o prefixo. Dentro de um bloco server a mesma coisa se escreve mount admin at "/admin".

Ver as rotas registradas#

dataforge
cycle r in Kiln.routes(api):
    out r["method"], r["path"], r["params"]