Decouple your express applications using the amazing express-decorator-router
Tags: node, javascript, express
Published: 2020-09-12 17:51:21

### Sick of that bunch of route files for our beloved express? 
### Looking for a way to use middleware and inject dependencies succinctly and clearly? 
### Looking for that package that will help you test your projects by decoupling intelligently?

**Your problems end here and now**, I present to you the package whose premise **doesn't need transpilation**, and **can be used with koa, express or any package following express API**.

![](https://media3.giphy.com/media/5p2wQFyu8GsFO/giphy.gif?cid=ecf05e47tgdq0t71f7ewzbyciwpetdpc1t4dsb8ewnvn9to3&rid=giphy.gif)

You who want to escape from transpilation and are a hipster who likes the good old vanilla JS.

This package is intended to avoid unnecessary creation of two files where one contains the route definition and the other has the function that handles the route request/response processes, leaving simpler maintenance and more scalable code.

With **only 32kb** minified (source: [bundlephobia](https://bundlephobia.com/result?p=express-decorator-router@0.1.1)), being able to inject the dependencies in a "manual" way or with the extremely tough tool [awilix](https://github.com/jeffijoe/awilix)

# Cool dude! But, how do I use it in practice?
![](https://i.giphy.com/media/26gR0YFZxWbnUPtMA/giphy.webp)

## Without Awilix
First let's talk about the root mode  👨‍💻👩‍💻

### Registering your controllers with that mastery 🧐
The **useControllers** method uses **two parameters**, the **first is the routing mechanism and the second is a glob expression** that has the responsibility of finding all controllers that match the pattern of the expression.

#### server.js
```javascript
const express = require('express')
const { resolve } = require('path')
const { useControllers } = require('express-decorator-router')

const app = express()
const router = express.Router()

app.use(express.json())

app.use('/api', useControllers({
	controllerExpression: `${resolve('src')}/**/controller.js`,
	router
}))

app.listen(3000, () => console.log('🔮 magic happens on port 3000'))
```

The **controller** function **returns a high order function where the decorator definition is made** by associating a decorator with a class method as seen in the example above.

#### controller.js
```javascript
const {
	get,
	put,
	del,
	post,
	controller
} = require('express-decorator-router')

class UserController {

	getUsers(ctx) {
		return ctx.response.json({ message: 'get all users' })
	}

	postUser(ctx) {
		const { user } = ctx.response.body
		return ctx.response.json({ message: `create user with name ${user}` })
	}

	putUser(ctx) {
		const { id } = ctx.request.params
		const { user } = ctx.request.body
		return ctx.response.json({ message: `update user with name ${user} with id ${id}` })
	}

	deleteUser(ctx) {
		const { id } = ctx.request.params
		return ctx.response.json({ message: `delete user with id ${id}` })
	}
}

module.exports = controller('/users')(UserController, {
	getUsers: get(),
	postUser: post(),
	putUser: put('/:id'),
	deleteUser: del('/:id')
})
```
## With Awilix

Awilix has a pretty simple API (but with many possible ways to invoke it). At minimum, you need to do 3 things:

- Create a container
- Register some modules in it
- Resolve and use!

To make your life easier it already comes as an **internal dependency** so you will not need to install the same.

Now let's take a look at how it becomes even simpler to decouple your application with it.

### Registering your controllers is even easier 🤩
#### server.js 

```javascript
const express = require('express')
const { resolve } = require('path')
const userService = require('./users/service')
const { useAwilixControllers, awilix, scopePerRequest } = require('express-decorator-router')

const app = express()
const router = express.Router()
const container = awilix.createContainer()

container.register({
	userService: awilix.asValue(userService).scoped()
})

app.use(express.json())
app.use(scopePerRequest(container))

app.use('/api/user', useAwilixControllers({
	controllerExpression: `${resolve('src')}/**/controller.js`,
	router
}))

app.listen(3200, () => console.log('🔮 magic happens on port 3200'))
```

#### controller.js
```javascript
const {get, controller, inject } = require('express-decorator-router')

const getUsers = (req, res) => {
	const { userService } = req
	return res.json(userService.getUsers())
}

module.exports = controller('/users', inject('userService'))({
	getUsers
}, {
	getUsers: get()
})
```

Now you can be creative and discover highly scalable, testable and decoupled applications.

This package can be found on **awesome-express** list on **middleware** category
{% github https://github.com/rajikaimal/awesome-express no-readme %}

You can go even deeper into the repository documentation:
{% github https://github.com/LucasMendesl/express-decorator-router %}


![](https://i.imgur.com/02s3CgS.png)