[](https://www.npmjs.com/package/awilix-router-core) [](https://david-dm.org/jeffijoe/awil
npm install awilix-router-core






> This package is intended for use with HTTP libraries that want to configure routes using ESNext decorators or a builder pattern.
- awilix-router-core
- Table of Contents
- Install
- Example
- With decorators
- With builder pattern
- For framework adapter authors
- API
- Route Declaration
- Builder
- createController(targetClassOrFunction)
- Decorators
- route(path)
- before(middlewares) and after(middlewares)
- verbs(httpVerbs)
- Verb shorthands
- Extracting route config
- getStateAndTarget(functionOrClassOrController)
- rollUpState(state)
- findControllers(pattern, opts)
- Author
With npm:
```
npm install awilix-router-core
Or with yarn
``
yarn add awilix-router-core
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.
`js
// 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)
}
}
`
`js
// 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 apiapi
.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 `
before: [authenticate()],
})
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.
As mentioned earlier, this package exposes the user-facing route declaration API, as well as utilities needed for framework adapter authors.
There are 2 flavors of route declaration: builder and ESNext decorators.
The builder API's public top level exports are:
`js`
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][http-verbs] 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.
If you have enabled decorator support in your transpiler, you can use the decorator API.
The decorator API exports are:
`js
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:
`js
@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:
`js`
@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:
`js`
@verbs([HttpVerbs.GET, HttpVerbs.POST])
method() {}
#### Verb shorthands
GET, POST, etc.
Example:
`js
@route('/todos')
class Controller {
// GET /todos
// POST /todos
@GET()
@POST()
method1() {}
// PATCH /todos/:id
@route('/:id')
@PATCH()
method2() {}
}
`
This section is for framework adapter authors. Please see [awilix-koa][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 statetarget
> and properties, where target is the class/function to build up (using container.build)
> in order to get an object to call methods on.
`js`
import {
getStateAndTarget,
rollUpState,
findControllers,
} from 'awilix-router-core'
Given a controller (either from createController or a decorated class), returns a state-target tuple.
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.
Using fast-glob, loads controllers from matched files.
opts is a merge of glob options to pass into glob for pattern matching and the esModules property which, when set to true returns a Promise that loads controller modules via dynamic import() (for async/ ES modules usage).
Returns an array (or a Promise` that resolves to an array) of state-target tuples.
Jeff Hansen — @Jeffijoe
[http-verbs]: /src/http-verbs.ts
[awilix-koa]: https://github.com/jeffijoe/awilix-koa