Routing
Routing
A router maps an intention to the code that answers it. Stone.js has one router, and it behaves identically wherever the app runs: the routes you write for a Node service are the routes that drive navigation in the browser. This section covers it end to end.
#The mental model
Every route is a pairing: a way to recognise an intention (a method and a path pattern) and a handler to run when it matches. The handler reads values off the event and returns data; it never touches a platform request object. That is what keeps the same routes valid across every context.
A route names an intention. A handler answers it. Everything else in this section is detail on those two.
#Install and enable it
Routing is a module, so it has to be enabled on the application before any route runs. Add its decorator, or hand its blueprint to the manifest, alongside an adapter to run it on. Without this step the routes below are collected and never matched.
npm i @stone-js/routerimport { StoneApp } from '@stone-js/core'
import { Routing } from '@stone-js/router'
import { NodeHttp } from '@stone-js/node-http-adapter'
@Routing() // the router becomes the app's event handler
@NodeHttp({ default: true }) // an adapter to run it on
@StoneApp({ name: 'tasks' })
export class Application {}import { defineStoneApp } from '@stone-js/core'
import { routerBlueprint } from '@stone-js/router'
import { nodeHttpAdapterBlueprint } from '@stone-js/node-http-adapter'
export const App = defineStoneApp(
{ name: 'tasks' },
[routerBlueprint, nodeHttpAdapterBlueprint]
)#Define a route
Group related routes under a controller with a base path, then bind methods to verbs and sub-paths. Both paradigms produce the same routes.
import { EventHandler, Get, Post } from '@stone-js/router'
import { IncomingHttpEvent } from '@stone-js/http-core'
@EventHandler('/tasks') // a controller: a base path + its routes
export class TaskController {
constructor ({ tasks }: { tasks: TaskService }) { this.tasks = tasks }
@Get('/') // GET /tasks
list (event: IncomingHttpEvent) { return this.tasks.list() }
@Post('/', { name: 'tasks.create' }) // POST /tasks, a named route
create (event: IncomingHttpEvent) { return this.tasks.add(event.get<string>('title')) }
}import { defineEventHandler, defineRoutes } from '@stone-js/router'
const TaskController = ({ tasks }) => ({
list: () => tasks.list(),
create: (event) => tasks.add(event.get('title'))
})
export const routes = defineRoutes([
[defineEventHandler(TaskController, 'list'), { path: '/tasks', method: 'GET' }],
[defineEventHandler(TaskController, 'create'), { path: '/tasks', method: 'POST', name: 'tasks.create' }]
])#What the section covers
Routing is large, so it is split into focused pages. Read them in order for a full tour, or jump to what you need: