Stone.jsDocs
Paradigm

Routing

Parameters & constraints

A path can capture parts of the URL as named parameters. You read them off the event like any other intention, and you can make them optional, greedy, or subject to a pattern, so a route only matches when the shape is right.

#Declaring and reading parameters

Prefix a segment with : to capture it. Inside the handler, read it with event.get(name), exactly as you read query or body values, so the handler never cares where the value came from.

app/Tasks.tsdeclarativeimperative
import { Get, EventHandler } from '@stone-js/router'
import { IncomingHttpEvent } from '@stone-js/http-core'

@EventHandler('/tasks')
export class TaskController {
  // Required param, constrained to digits.
  @Get('/:id', { rules: { id: /\d+/ } })
  show (event: IncomingHttpEvent) {
    return this.tasks.find(event.get<string>('id'))
  }

  // Optional param with a default.
  @Get('/page/:n?', { defaults: { n: '1' } })
  page (event: IncomingHttpEvent) {
    return this.tasks.page(Number(event.get<string>('n')))
  }

  // Catch-all: matches the rest of the path.
  @Get('/files/:path*')
  file (event: IncomingHttpEvent) {
    return this.storage.read(event.get<string>('path'))
  }
}
import { defineEventHandler, defineRoutes } from '@stone-js/router'

export const routes = defineRoutes([
  [defineEventHandler(TaskController, 'show'),
    { path: '/tasks/:id', method: 'GET', rules: { id: /\d+/ } }],
  [defineEventHandler(TaskController, 'page'),
    { path: '/tasks/page/:n?', method: 'GET', defaults: { n: '1' } }],
  [defineEventHandler(TaskController, 'file'),
    { path: '/tasks/files/:path*', method: 'GET' }]
])

#Parameter syntax

PatternTypeDescription
:idrequiredCaptures exactly one segment; the route fails to match if it is absent.
:id?optionalMatches with or without the segment; pair with defaults for a fallback value.
:path*catch-all (zero or more)Captures the rest of the path, slashes included.
:path+catch-all (one or more)Like *, but requires at least one segment.

#Constraints with rules

The rules option maps a parameter to a pattern. The route matches only when the parameter satisfies it, so /tasks/42 reaches the handler while /tasks/abc does not, and can fall through to another route.

app/Tasks.tsts
@Get('/:id', { rules: { id: /\d+/ } })        // digits only
@Get('/:slug', { rules: { slug: '[a-z-]+' } }) // a string pattern works too

Stone.js

Your app exists in every runtime. Until you run it.

An open-source project by Stone Foundation
Created by Mr. Stone (Evens Pierre)