Middleware is a convenient way to validate requests, modify responses, and otherwise inject yourself into the HTTP request/response lifecycle.

Grind supports Connect middleware via Express, for full information on Connect middleware, visit the Connect site.

Global middleware is registered via app.routes.use():

app.routes.use((req, res, next) => {
  if(req.query.password !== 'secret') {
    // This will abort the request 
    return next(new ForbiddenError)
  }
 
  // If they have the correct password 
  // call next and continue the request 
  next()
})

This middleware will now apply to all routes registered after it’s been added. Any routes registered before will not have the middleware.

Unlike Express, you can’t pass a path to use. If you’d like to register middleware on a path, you’ll need to add it to a group with a prefix.

Group middlware provides an easy way to apply middleware to a collection of routes. Middleware defined on a group will apply only to routes registered in that group, even if two groups share the same prefix.

You can pass middleware to a group as part of it’s options:

app.routes.group({
  prefix: '/users'
  before: [ formBodyParser, jsonBodyParser ],
  after: [ responseInspector ]
}, routes => {
  routes.get('/', …)
})

You can also add middleware to the group via use:

app.routes.group(routes => {
  // Before middleware 
  routes.use(formBodyParser, jsonBodyParser)
 
  // Add routes 
  routes.post('/test', …)
 
  // After middleware 
  routes.use(responseInspector)
})

Middleware in groups cascade downward, so if you nest groups each group will inherit middleware from it’s ancestors and apply them all contained routes:

app.routes.group(routes => {
  routes.use(someMiddleware)
  routes.get('hello')
 
  routes.group(routes => {
    routes.use(otherMiddleware)
    routes.get('goodbye')
  })
})

In this example, the hello route will run with someMiddleware, and the goodbye route will run with someMiddleware and otherMiddleware. Each middleware will be called in the order it’s registered.

To add middleware to a specific route, you have a couple of options.

You can pass middleware to a route as part of it’s action:

app.routes.post('/', {
  before: [ formBodyParser, jsonBodyParser ],
  after: [ responseInspector ],
  action: …
})

You can also add middleware to the route after it’s been created:

app.routes.post('/', …).before(formBodyParser, jsonBodyParser).after(responseInspector)

Passing functions around for middleware can become a bit unwieldy, so Grind let‘s you register middleware onto the router with aliases.

To register middleware, simply call registerMiddleware on the Router:

export function MiddlewareProvider(app) {
  app.routes.registerMiddleware('auth', (req, res, next) => {
    if(req.query.password !== 'secret') {
      return next(new ForbiddenError)
    }
 
    next()
  })
}
 
MiddlewareProvider.priority = 100

Once you‘ve registered your alias, you can use it anywhere you’d normally add middleware:

app.routes.use('auth')
 
app.routes.group({ before: 'auth' }, …)
app.routes.group(routes => {
  routes.use('auth')
})
 
app.routes.post('/', { before: [ 'auth' ], … })
app.routes.post('/', …).before('auth')
Edit