Essentials
Event handlers
A handler is the smallest piece of your domain: it takes an IncomingEvent and returns a result. Everything the framework does, from adapters to middleware, exists to deliver a clean intention to a handler and carry its result back out.
#The contract
A handler receives the event and returns a value (or a response). It reads inputs with event.get() and returns plain data; the context serialises it. That is the whole contract, and it is identical in every runtime.
import { EventHandler, Get } from '@stone-js/router'
import { IncomingHttpEvent } from '@stone-js/http-core'
@EventHandler('/hello')
export class HelloController {
@Get('/')
greet (event: IncomingHttpEvent) {
return { message: `Hello ${event.get<string>('name', 'World')}` }
}
}import { defineEventHandler, defineRoutes } from '@stone-js/router'
const greet = (event) => ({ message: `Hello ${event.get('name', 'World')}` })
export const routes = defineRoutes([
[defineEventHandler(greet), { path: '/hello', method: 'GET' }]
])Intention in, result out. A handler never learns which platform delivered the intention.
#The three forms
A handler can be any of the three forms, chosen to fit the job:
// Class: bindings arrive in the constructor (best with decorators).
@EventHandler('/tasks')
class TaskController { constructor ({ tasks }) { this.tasks = tasks } /* ... */ }
// Factory: receives the container, returns the handler object.
const TaskController = ({ tasks }) => ({ list: () => tasks.list() })
// Function: bare logic, no container. Perfect for tiny endpoints.
const ping = (event) => ({ pong: event.get('n', 1) })#Multiple handlers
A minimal app has one handler. Add @Routing() and you can have as many as you like, each bound to its own intention; the router delegates the right event to the right handler. See the Routing section for the full story.