Stone.jsDocs
Paradigm

Middleware

Registering middleware

The same pipe can run for the whole app, for one group, or for a single route. Where you attach it decides its scope; a couple of options decide its order and let routes opt out.

#Scopes

ScopeTypeDescription
Globalapp / kernelRuns for every event. Set on the app (stone.middleware) or mark the middleware global.
Groupcontroller / childrenIn a controller's or group's middleware array; runs for its routes.
Routeper routeIn a route's middleware array; runs for that route only.
app/Application.tsdeclarativeimperative
import { StoneApp, Middleware } from '@stone-js/core'

// Global: runs for every event. 'global: true' registers it kernel-wide.
@Middleware({ global: true, priority: 10 })
export class RequestId { /* ... */ }
import { defineStoneApp } from '@stone-js/core'
import { requestId } from './middleware/requestId'

export const App = defineStoneApp(
  { name: 'tasks', middleware: [requestId] },   // global middleware
  [/* blueprints */]
)

#Per route and per group

app/Tasks.tsts
@EventHandler('/tasks', { middleware: [requireAuth()] })   // whole controller
export class TaskController {
  @Post('/', { middleware: [validate({ body: NewTask })] })  // one route, in addition
  create (event) { /* ... */ }
}

#Order, priority and opting out

  • Order: global first, then group, then route; within a list, top to bottom.
  • Priority: give a middleware a priority to move it earlier or later among its peers.
  • Alias: register a middleware under an alias and refer to it by name where that reads better.
  • Opt out: a route can drop an inherited middleware with excludeMiddleware.
app/Tasks.tsts
@Get('/public', { excludeMiddleware: [requireAuth] })   // skip the group's guard here
public () { /* no auth */ }
OptionTypeDefaultDescription
globalbooleanfalseRegister as kernel-wide middleware.
prioritynumber·Execution order among peers (lower runs earlier).
aliasstring | string[]·Name(s) to reference the middleware by.
paramsunknown[]·Arguments passed to the middleware.

#Two layers: kernel and adapter

Almost all middleware is kernel middleware: it runs on the normalised IncomingEvent, inside the per-event container, everything on this page so far. There is also a rarer adapter middleware that runs at the integration edge, on the platform's raw cause and response, before the kernel builds the event.

app/middleware/rawTiming.tsts
import { defineAdapterMiddleware } from '@stone-js/core'

// Runs on the raw platform context, outside the kernel. For platform-level
// concerns only (raw timing, low-level headers); use kernel middleware otherwise.
export const rawTiming = defineAdapterMiddleware((context, next) => next(context))

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)