Documentation
Docs
Introduction
Getting Started
Tutorial: build an app
Core Concepts
Routing
Server-Side Rendering
Mimir, state management
Pages & Layouts
API Routes
Styling & Theming
Building & Deploying
API Reference
Guides
Recipes
FAQ (use cases)
Validation and options
This page covers the rest of the API surface: per-route options, the automatic 405 Method Not Allowed,
input validation, and body limits.
Per-route options
app.api(method, path, opts, handler) accepts an options object between the path and the handler. It is
passed to the underlying server registration, so it is where transport-level settings live (for example body
size limits for a specific upload endpoint):
Omit opts for the common case:
Automatic 405 Method Not Allowed
When you register one or more methods for a path, rune automatically answers other methods to that path
with 405 and an allowed list, you do not write that handler:
This keeps your API honest (a wrong method gets a correct 405, not a confusing 404) with zero extra code.
Validate input , do not trust the client
await req.json() parses whatever the client sent (content-type-independent, single-use). Validate it in the handler
before using it. A simple guard:
For larger schemas, write a small validator module (or use a schema library you ship) and run it at the top
of each handler. The principle is the same: reject bad input with a 400 and a clear message; never pass
unvalidated input to your data layer.
A reusable validator
Body size limits
Two levels:
- App-wide:
createApp({ maxBodySize, maxWsMessageSize })sets defaults for the whole server. - Per-route: the
optsargument (above) overrides for one endpoint.
Set conservative limits, an unbounded body is a denial-of-service vector. Raise it only for endpoints that genuinely need large payloads (uploads), and validate the content there.
Permissions and the API
API handlers run under the same permission grant as the rest of the app. If a
handler reads files, the app needs fs; if it calls an upstream service, it needs net. Scope these in
ekko.json so a handler can only reach what it should:
Idempotency and methods
Follow HTTP semantics so clients, caches, and the automatic 405 behave predictably:
GET, read, no side effects, cacheable.POST, create / non-idempotent action.PUT, replace a resource (idempotent).PATCH, partial update.DELETE, remove (idempotent).
That completes API Routes. Next: styling the app, Styling → SCSS.