/middle-router

Route urls on both client and server through middleware

Primary LanguageJavaScriptMIT LicenseMIT

middle-router

npm Version Greenkeeper badge Build Status

MIT License JS Standard Style

Route urls through middleware functions on both client and server.

middle-router is a universal front-end router for routing urls changes through a series of async middleware functions. This allows you to perform multiple tasks when the url changes, instead of just updating the view.

middle-router uses path-to-regexp to match paths, so it should behave much like express 4.x paths. It also uses middle-run to run the middleware series.

Usage

router.js

import Router from 'middle-router'

export default Router()
  .use(async ({ context, next }) => {
    let start = Date.now()
    await next() // start next middleware, wait for control to return
    context.totalMs = Date.now() - start
  })

  .use('/accounts', Router()
    .use('/users/:userId', async ({ params, resolve, beforeExit, exiting }) => {
      setupListeners()
      beforeExit(event => {
        if (isFormDirty) return 'Are you sure you want to leave?'
      })

      resolve(UserView({ id: params.userId })) // yields control back upstream

      await exiting // only do this after resolve, or it won't resolve until next url change!!
      cleanupListeners()
    })
  )

server-client.js

import router from './router.js'
import { Router } from 'express'
import ReactDOMServer from 'react-dom/server'

export default Router()
  .use(async (req, res, next) {
    try {
      let view = await router.route(req.url, res.locals.state)
      res.send(ReactDOMServer.renderToString(view))
    } catch (err) {
      next(err)
    }
  })

client.js

import router from './router.js'
import ReactDOM from 'react-dom'

router
  .on('route', async (args, routing) => {
    try {
      let view = await routing
      ReactDOM.render(view, document.getElementById('view'))
    } catch (error) {
      ReactDOM.render(<Error error={error}/>, document.getElementById('view'))
    }
  })
  .start()

Note: These usage examples use Express and React, and resolve each url to a React element. middle-router has no dependency on these, and can be used with whatever libraries you like.

API

Full API documentation is in the GitHub Wiki

Async Middleware

middle-router can work with any promised-based async middleware, but it was designed specifically for async functions. Inspired by koa's yield next, middle-router allows you to await next() so you can next() "downstream" and the await for control to flow back "upstream".

License

This software is free to use under the MIT license. See the LICENSE-MIT file for license text and copyright information.