Skip to content

Routing

All standard HTTP methods are available as app methods: get, post, put, delete, patch, options, head.

app:get("/hello", function(req, res)
res:send("hi")
end)
app:post("/items", function(req, res)
res:status(201):json({ ok = true })
end)

Handlers receive a Request and a Response.

Path segments prefixed with : are captured as params and exposed on req.params:

app:get("/users/:id/posts/:post_id", function(req, res)
res:json({ user = req.params.id, post = req.params.post_id })
end)

Params are always strings — /users/42 yields req.params.id == "42".

app:group(prefix) gathers routes under a shared prefix — like an Express Router mounted on a path, or a Fastify plugin registered with a prefix. The usual shape is a body callback that receives the group; groups nest, and a "/" path maps to the prefix itself:

app:group("/api", function(api)
api:get("/", handler) -- GET /api
api:get("/users/:id", handler) -- GET /api/users/42
api:group("/v2", function(v2) -- groups nest
v2:get("/users", handler) -- GET /api/v2/users
end)
end)

The group is also returned, so the callback is optional:

local api = app:group("/api")
api:get("/ping", function(req, res) -- GET /api/ping
res:send("pong")
end)

Groups also take middlewares, running before every route in the group — see group middlewares.

Requests that match no route get a 404 with a JSON body.

Errors thrown inside a handler are caught and answered with a 500.