Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/davesag/route-async
A route wrapper allowing use of async / await syntax in Express route controllers
https://github.com/davesag/route-async
async async-await es6-javascript expressjs
Last synced: about 1 month ago
JSON representation
A route wrapper allowing use of async / await syntax in Express route controllers
- Host: GitHub
- URL: https://github.com/davesag/route-async
- Owner: davesag
- License: mit
- Created: 2018-08-07T05:13:00.000Z (over 6 years ago)
- Default Branch: develop
- Last Pushed: 2024-04-23T05:57:33.000Z (8 months ago)
- Last Synced: 2024-05-02T00:12:31.865Z (8 months ago)
- Topics: async, async-await, es6-javascript, expressjs
- Language: JavaScript
- Size: 1.76 MB
- Stars: 8
- Watchers: 3
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# route-async
A route-wrapper allowing use of `async` / `await` syntax in [`Express`](https://expressjs.com) route controllers.
[![NPM](https://nodei.co/npm/route-async.png?compact=true)](https://nodei.co/npm/route-async/)
## To Use
```sh
npm install route-async
```## Wrap an `async` route
Assuming you have some async helper function called `someAsync`, you might have a route looking a bit like this:
```js
const asyncRoute = require('route-async')
const someAsync = require('./helpers/someAsync')const myRoute = async (req, res) => {
const result = await someAsync(req.body)
res.json(result)
}module.exports = asyncRoute(myRoute)
```The `asyncRoute` wrapper simply takes your route and wraps it, such that the `async` promise is either resolved internally, or if rejected a `next` function is called. The default `next` is just `console.error` and you can supply your own.
### What about if my route wants `next`
Your route should not attempt to handle its own errors, but simply throw an `Error`, or even better an [`HttpError`](https://github.com/jshttp/http-errors) that gets caught by the `async-route` wrapper.
This keeps your core route code much simpler.
## Testing `async` routes
The following example leverages [`mocha`](https://mochajs.org), [`sinon`](https://sinonjs.org), and [`proxyquire`](https://github.com/thlorenz/proxyquire) to unit test the above route by supplying a `spy` in the place of the `next` function.
```js
const { expect } = require('chai')
const { spy, stub } = require('sinon')
const proxyquire = require('proxyquire')describe('src/routes/myRoute', () => {
const mockSomeAsync = stub()const myRoute = proxyquire('../../src/routes/myRoute', {
'./helpers/someAsync': mockSomeAsync
})const req = { body: 'some body' }
const res = { json: stub() }
const next = spy()const resetStubs = () => {
res.json.resetHistory()
next.resetHistory()
}context('no errors', () => {
const result = 'some result'before(async () => {
mockSomeAsync.resolves(result)
await myRoute(req, res, next)
})after(resetStubs)
it('called someAsync with the right data', () => {
expect(mockSomeAsync).to.have.been.calledWith(req.body)
})it('called res.json with the right data', () => {
expect(res.json).to.have.been.calledWith(result)
})it("didn't call next", () => {
expect(next).not.to.have.been.called
})
})context('has errors', () => {
const error = 'some error'before(async () => {
mockSomeAsync.rejects(error)
await myRoute(req, res, next)
})after(resetStubs)
it('called someAsync with the right data', () => {
expect(mockSomeAsync).to.have.been.calledWith(req.body)
})it("didn't call res.json", () => {
expect(res.json).not.to.have.been.called
})it('called next with the error', () => {
expect(next).to.have.been.calledWith(error)
})
})
})
```## Development
### Branches
| Branch | Status | Coverage | Audit | Comments |
| -------- | ------- | --------- | ----- | --------- |
| `develop` | [![CircleCI](https://circleci.com/gh/davesag/route-async/tree/develop.svg?style=svg)](https://circleci.com/gh/davesag/route-async/tree/develop) | [![codecov](https://codecov.io/gh/davesag/route-async/branch/develop/graph/badge.svg)](https://codecov.io/gh/davesag/route-async) | [![Vulnerabilities](https://snyk.io/test/github/davesag/route-async/develop/badge.svg)](https://snyk.io/test/github/davesag/route-async/develop) | Work in progress |
| `main` | [![CircleCI](https://circleci.com/gh/davesag/route-async/tree/main.svg?style=svg)](https://circleci.com/gh/davesag/route-async/tree/main) | [![codecov](https://codecov.io/gh/davesag/route-async/branch/main/graph/badge.svg)](https://codecov.io/gh/davesag/route-async) | [![Vulnerabilities](https://snyk.io/test/github/davesag/route-async/main/badge.svg)](https://snyk.io/test/github/davesag/route-async/main) | Latest release |### Prerequisites
- [NodeJS](htps://nodejs.org). I use [`nvm`](https://github.com/creationix/nvm) to manage Node versions — `brew install nvm`.
### Initialisation
```sh
npm install
```### Test it
- `npm test` — runs the unit tests
- `npm run test:unit:cov` — runs the tests with code coverage output.### Lint it
```sh
npm run lint
```## Contributing
Please see the [contributing notes](CONTRIBUTING.md).