Stone.jsDocs
Paradigm

Routing

Route middleware

Middleware is where a route states its guarantees in plain sight: who may call it, what the input must look like, what happens around it. Auth, authorization and validation from the Build section are all just middleware attached here.

#Attaching middleware

Add a middleware array to a route, a controller, or a group. Group middleware runs for every route inside; route middleware runs in addition, after the group's, in the order listed.

app/Tasks.tsdeclarativeimperative
import { EventHandler, Get, Post, Delete } from '@stone-js/router'
import { requireAuth, requireScopes } from '@stone-js/auth'
import { authorize } from '@stone-js/authz'
import { validate } from '@stone-js/validation'

@EventHandler('/tasks', { middleware: [requireAuth()] })   // group-wide
export class TaskController {
  @Get('/')
  list () { /* just requireAuth, from the group */ }

  @Post('/', { middleware: [validate({ body: NewTask }), requireScopes('tasks:write')] })
  create (event) { /* group + route middleware, in order */ }

  @Delete('/:id', { middleware: [authorize('delete', 'Task')] })
  remove (event) { /* ... */ }
}
import { defineEventHandler, defineRoutes } from '@stone-js/router'
import { requireAuth, requireScopes } from '@stone-js/auth'
import { authorize } from '@stone-js/authz'
import { validate } from '@stone-js/validation'

export const routes = defineRoutes([
  [defineEventHandler(TaskController, 'list'),
    { path: '/tasks', method: 'GET', middleware: [requireAuth()] }],
  [defineEventHandler(TaskController, 'create'),
    { path: '/tasks', method: 'POST', middleware: [requireAuth(), validate({ body: NewTask }), requireScopes('tasks:write')] }],
  [defineEventHandler(TaskController, 'remove'),
    { path: '/tasks/:id', method: 'DELETE', middleware: [requireAuth(), authorize('delete', 'Task')] }]
])

#Order and opting out

  • Order: group middleware first, then route middleware, top to bottom. Put guards before transforms (authenticate, then validate).
  • Opt out: a route in a guarded group can drop an inherited middleware with excludeMiddleware.
app/Tasks.tsts
@EventHandler('/tasks', { middleware: [requireAuth()] })
export class TaskController {
  // A public endpoint inside an otherwise-guarded controller.
  @Get('/public', { excludeMiddleware: [requireAuth] })
  public () { /* no auth here */ }
}

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)