Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

awilix-router-core

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

awilix-router-core

[![npm](https://img.shields.io/npm/v/awilix-router-core.svg?maxAge=1000)](https://www.npmjs.com/package/awilix-router-core) [![dependency Status](https://img.shields.io/david/jeffijoe/awilix-router-core.svg?maxAge=1000)](https://david-dm.org/jeffijoe/awil

  • 1.6.1
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
7.5K
decreased by-1.06%
Maintainers
1
Weekly downloads
 
Created
Source

awilix-router-core

npm dependency Status devDependency Status Build Status Coveralls npm npm

This package is intended for use with HTTP libraries that want to configure routes using ESNext decorators or a builder pattern.

Table of Contents

Install

With npm:

npm install awilix-router-core

Or with yarn

yarn add awilix-router-core

Example

The end-user of the routing library will be able to use decorators or a builder pattern to declaratively set up their routes, middleware and methods.

Note: in the examples below, an ES6 default export is used, but named exports and multiple exports per file are supported.

With decorators

// You may re-export these as well.
import { route, before, GET, verbs, HttpVerbs } from 'awilix-router-core'

import bodyParser from 'your-framework-body-parser'
import authenticate from 'your-framework-authentication'

@before(bodyParser())
@route('/news')
export default class NewsController {
  constructor ({ service }) {
    this.service = service
  }

  @GET()
  async find (ctx) {
    ctx.body = await this.service.doSomethingAsync()
  }

  @route('/:id')
  @GET()
  async get(ctx) {
    ctx.body = await this.service.getNewsOrWhateverAsync(ctx.params.id)
  }

  @route('(/:id)')
  @verbs([HttpVerbs.POST, HttpVerbs.PUT])
  @before(authenticate())
  async save (ctx) {
    ctx.body = await this.service.saveNews(ctx.params.id, ctx.request.body)
  }
}

With builder pattern

// You may re-export these as well.
import { createController } from 'awilix-router-core'

import bodyParser from 'your-framework-body-parser'
import authenticate from 'your-framework-authentication'

// Can use a factory function or a class.
const api = ({ service }) => ({
  find: async () => (ctx.body = await service.doSomethingAsync()),
  get: async (ctx) => (ctx.body = await service.getNewsOrWhateverAsync(ctx.params.id)),
  save: async (ctx) => (ctx.body = await service.saveNews(ctx.params.id, ctx.request.body))
}) 

export default createController(api)
  .before(bodyParser())
  .prefix('/news')
  .get('', 'find') // <- "find" is the method on the result from `api`
  .get('/:id', 'get') // <- "get" is the method on the result from `api`
  .verbs([HttpVerbs.POST, HttpVerbs.PUT], '/:id', 'save', {
    // "save" is the method on the result from `api`
    before: [authenticate()]
  })

For framework adapter authors

The framework adapter will use the tools provided by this package to extract routing config from decorated classes and register it in the router of choice.

Check out the awilix-koa reference implementation, as well as the API docs here.

API

As mentioned earlier, this package exposes the user-facing route declaration API, as well as utilities needed for framework adapter authors.

Route Declaration

There are 2 flavors of route declaration: builder and ESNext decorators.

Builder

The builder API's public top level exports are:

import { createController, HttpVerbs } from 'awilix-router-core'
createController(targetClassOrFunction)

Creates a controller that will invoke methods on an instance of the specified targetClassOrFunction.

The controller exposes the following builder methods:

  • .get|post|put|patch|delete|head|options|connect|all(path, method, opts): shorthands for .verbs([HttpVerbs.POST], ...) - see HttpVerbs for possible values.
  • .verbs(verbs, path, method, opts): registers a path mapping for the specified controller method.
  • .prefix(path): registers a prefix for the controller. Calling this multiple times adds multiple prefix options.
  • .before(middlewares): registers one or more middlewares that runs before any of the routes are processed.
  • .after(middlewares): registers one or more middlewares that runs after the routes are processed.

The optional opts object passed to .verbs can have the following properties:

  • before: one or more middleware that runs before the route handler.
  • after: one or more middleware that runs after the route handler.

Note: all builder methods returns a new builder - this means the builder is immutable! This allows you to have a common builder setup that you can reuse for multiple controllers.

Decorators

If you have enabled decorator support in your transpiler, you can use the decorator API.

The decorator API exports are:

import { 
  route, 
  before,
  after, 
  verbs,
  HttpVerbs,

  // The following are just shortcuts for `verbs([HttpVerbs..])`
  GET,
  HEAD,
  POST,
  PUT,
  DELETE,
  CONNECT,
  OPTIONS,
  PATCH,
  ALL
} from 'awilix-router-core'
route(path)

Class-level: adds a prefix to all routes in this controller.

Method-level: adds a route for the decorated method in the controller.

Has no effect if no verbs are configured.

Example:

@route('/todos')
class Controller {
  // GET /todos
  // POST /todos
  @GET()
  @POST()
  method1() {}

  // PATCH /todos/:id
  @route('/:id')
  @PATCH()
  method2() {}
}
before(middlewares) and after(middlewares)

Class-level: adds middleware to run before/after the routes are processed.

Method-level: adds middleware to run before/after the decorated method is processed.

Example:

@before([bodyParser()])
class Controller {
  @before([authenticate()])
  @after([compress()])
  method() {}
}
verbs(httpVerbs)

Class-level: not allowed.

Method-level: adds HTTP verbs that the route will match.

Has no effect if no routes are configured.

Example:

@verbs([HttpVerbs.GET, HttpVerbs.POST])
method() {}
Verb shorthands

GET, POST, etc.

Example:

@route('/todos')
class Controller {
  // GET /todos
  // POST /todos
  @GET()
  @POST()
  method1() {}

  // PATCH /todos/:id
  @route('/:id')
  @PATCH()
  method2() {}
}

Extracting route config

This section is for framework adapter authors. Please see awilix-koa for a reference implementation. If you need any help, please feel free to reach out!

The primary functions needed for this are getStateAndTarget, rollUpState, and findControllers.

NOTE: when referring to "state-target tuple", it means an object containing state and target properties, where target is the class/function to build up (using container.build) in order to get an object to call methods on.

import { getStateAndTarget, rollUpState, findControllers } from 'awilix-router-core'

getStateAndTarget(functionOrClassOrController)

Given a controller (either from createController or a decorated class), returns a state-target tuple.

rollUpState(state)

This will return a map where the key is the controller method name and the value is the routing config to set up for that method, with root paths + middleware stacks pre-merged.

findControllers(pattern, globOptions)

Using glob, loads controllers from matched files, with non-applicable files filtered out.

Returns an array of state-target tuples.

Author

Jeff Hansen — @Jeffijoe

FAQs

Package last updated on 22 Jan 2019

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc