Route methods
Map URLs to handler functions. Wapka supports all standard HTTP verbs:
local app = framework()
app:get("/users", handler) -- read
app:post("/users", handler) -- create
app:put("/users/:id", handler) -- full update
app:patch("/users/:id", handler) -- partial update
app:delete("/users/:id", handler) -- remove
app:head("/users", handler) -- headers only (also auto-matches GET)
app:any("/webhook", handler) -- any method
Path parameters
Capture dynamic URL segments with :name:
-- /blog/hello-world → ctx.params.slug = "hello-world"
app:get("/blog/:slug", function(ctx)
local post = api.posts.list({ search = ctx.params.slug })
return ctx:render("post", { post = post.items[1] })
end)
-- /blog/2026/05/launch-day → ctx.params.year, .month, .slug
app:get("/blog/:year/:month/:slug", function(ctx)
return {
year = ctx.params.year,
month = ctx.params.month,
slug = ctx.params.slug
}
end)
Wildcard routes
Capture everything after a path segment with *:
-- /files/docs/report.pdf → ctx.params.path = "docs/report.pdf"
app:get("/files/*path", function(ctx)
return { file = ctx.params.path }
end)
Route groups
Group routes under a common prefix — keeps large apps organized:
app:group("/api/v1", function()
app:get("/status", statusHandler) -- → /api/v1/status
app:get("/users", listUsers) -- → /api/v1/users
app:post("/users", createUser) -- → /api/v1/users
end)
app:group("/admin", function()
app:get("/dashboard", adminHome, { middleware = "admin" })
app:get("/users", adminUsers, { middleware = { "auth", "admin" } })
end)
Named routes + URL generation
Name a route so you can generate URLs from code — never hardcode URLs:
app:get("/blog/:slug", postHandler, { name = "blog.post" })
-- Generate URL anywhere:
local url = app:url("blog.post", { slug = "hello-world" })
-- → "/blog/hello-world"
Use this in templates, redirects, emails — update the route definition and all links follow.
Route options
The third argument to any route method is an options table:
app:post("/webhook/stripe", stripeHandler, {
name = "stripe.webhook", -- named route
middleware = { "json" }, -- route-level middleware
csrf = false, -- disable CSRF for this route
})
| Option | Type | Description |
|---|---|---|
name |
string | Named route for app:url() |
middleware |
string or table | Middleware for this specific route |
csrf |
boolean | Set false to skip CSRF check (webhooks) |
Error responses
Wapka handles missing routes automatically:
- 404 — No route matches the URL
- 405 — URL matches a route but with the wrong HTTP method
Your app doesn't need a catch-all unless you want custom 404 pages.
Next: Request & Environment — read incoming data.