3.2.1 • Published 6 years ago

@totemish/routing v3.2.1

Weekly downloads
-
License
MIT
Repository
github
Last release
6 years ago

Routing

Core Build Status codecov Commitizen friendly semantic-release downloads version license

Description

Totemish routing is a wrapper for Node.js native HTTP server. It doesn't use any magic wands and lets you go all the tough way through Node.js jungle. At its core, Totemish routing is built upon middleware that does exactly what you expect. You have many entry points to put your middleware to get desired results. All the middleware is then put into a pipeline that is executed on Node.js HTTP server's request and response. Routing in Totemish is based on using RegExp which gives you incredible control over the routing as well as incredible pain in whatever applicable. Totemish routing only relies on dependency-free @totemish/core.

Installation

NPM

npm i --save @totemish/routing

Yarn

yarn install @totemish/routing

Usage

Simple example (HTTP)

import { HttpRouter } from '@totemish/routing';
import { createServer } from 'http';

/**
 * Simple middleware to log incoming requests.
 */
const Logger = (ctx) => {
    console.log(`${ctx.req.method}: ${ctx.req.url}`);

    return ctx;
}

/**
 * Initialize router. If you want to dive right in, use emptyHttpTask
 */
const router = HttpRouter.empty();

/**
 * Tell the router that in has to use Logger middleware on all the nested routes.
 */
router.
  beforeEach(Logger)
  get('/', (ctx) => ctx.res.end('Hello from the index page!')
  get('/about', (ctx) => ctx.res.end('Under construction')
;

/**
 * Assign HTTP server to expose our router and start listening.
 */
createServer(rt.serve).listen(8000);

console.log('Server running on port 8000');

Building Route Map

When building your route map, you can create multiple routers and concat them with main Router with Router#concat where necessary.

You can chain methods to make your code more human readable.

When you define action for a route, you can put one singe action and wrap it up with middleware executed before and after the action. Alternatively, you can provide an array of actions that will be considered a pipeline and executed one after another. In case you have middleware defined to wrap up the action pipeline, these pieces of middleware will be added to the pipeline accordingly (before\after the pipeline).

import { HttpRouter } from '@totemish/routing';
import {
  CreateUser,
  ReturnResponse,
  SendActivationEmail,
  CheckUserExists,
  CheckPassword,
  CheckUserActivationStatus,
  ReturnResponse,
  UpdateUserStory
} from '../middleware/auth';

const GlobalRouter = HttpRouter.empty();
const AuthRouter = HttpRouter.empty();

AuthRouter
  .before(CheckUserExists)
  .post('/sign-up', [
    CreateUser,
    ReturnResponse,
    SendActivationEmail,
  ])
  .post('/sign-in', [
    CheckPassword,
    CheckUserActivationStatus,
    ReturnResponse,
    UpdateUserStory,
  ])
;

GlobalRouter
  .prefix('/api/v1', (api) => api
    // Add AuthController to GlobalController
    .prefix('/auth', (auth) => auth.concat(AuthRouter)
  )
);

Prefixing Routes

You can nest prefixes for groups of routes as deep as you like. As a monad, primary Router gets all the nested routers concatenated with it so in the end you have one single Router that holds all the route map you've described.

You can prefix routes in several ways. The easiest way is to use Router.for(prefix). All the routes attached to it will automatically get given prefix.

Another way is to use Router#prefix method that accepts a string \ RegExp prefix and a function that accepts and returns nested Router that has given prefix attached to all the routes you describe for it:

// ...

HttpRouter
  .for('/api')
  .prefix('/v1', (r) => r
    .get('/posts', GetPostsList) // /api/v1/posts
  )
;

Using Middleware

You can use middleware before or after each route defined in the router. There are two ways to define middleware that should be executed before the route action\pipeline:

// ...

HttpRouter.for('/api/v1/users')
  .beforeEach(CheckUserExistence, CheckUserActivationStatus)
  .put('/(\d+)', UpdateUserData)
  .post('/(\d+)/passwd', [
    UpdateUserPassword,
    SendEmailNotification('password_change'),
  ])
;

Links

3.2.1

6 years ago

3.2.0

6 years ago

3.1.1

6 years ago

3.1.0

6 years ago

3.0.10

6 years ago

3.0.9

6 years ago

3.0.8

6 years ago

3.0.7

6 years ago

3.0.6

6 years ago

3.0.5

6 years ago

3.0.4

6 years ago

3.0.3

6 years ago

3.0.2

6 years ago

3.0.1

6 years ago

3.0.0

6 years ago

2.1.0

6 years ago

2.0.2

6 years ago

2.0.1

6 years ago

2.0.0

6 years ago

1.4.1

6 years ago

1.4.0

6 years ago

1.3.1

6 years ago

1.3.0

6 years ago

1.2.0

6 years ago

1.1.1

6 years ago

1.1.0

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago