hoangvvo / next-connect

The TypeScript-ready, minimal router and middleware layer for Next.js, Micro, Vercel, or Node.js http/http2
https://www.npmjs.com/package/next-connect
MIT License
1.64k stars 65 forks source link

Support async middleware chains #146

Closed UncleClapton closed 2 years ago

UncleClapton commented 3 years ago

Hello! I'm trying to implement a response time calculator in a Next API Route package I'm developing, and running into a roadblock.

The middleware stack currently runs synchronously, which prevents middleware from executing code after an async handler has been resolved. Instead, the stack unravels after an awaited call, executing code after next() in a middleware while doing so. The example below illustrates this.

Would there be any interest in a PR which changes this behavior and adds accompanying documentation?

The simplest method would be to change next() to return the result of it's expression. This would let users form async middleware chains in their applications, resolving the issue described above. It also has the benefit of being a non-breaking change.

The only major limitation is that async middleware would be all or nothing. Any middleware that fails to await or return the result of next() would break the async chain. This could cause some major confusion, and would need to be well documented. The same behavior can be found in other libraries such as koa.js and the long awaited Express v5, however, so it's not an entirely new concept.

Example

import nc from 'next-connect';
import { someAsyncWork } from './another-module';

const middleware = (req, res, next) => {
  console.log('1');

  await next(); // await has no bearing in the current version, however with the proposed solution, it would.

  console.log('4');
};

const handler = async (req, res) => {
  console.log('2');

  const someData = await someAsyncWork();
  res.status(200).json(someData);

  console.log('3');
};

export default nc()
  .use(middleware)
  .get('/', handler);

Output

Expected Actual
1 1
2 2
3 4
4 3
hoangvvo commented 3 years ago

Yeah I think this would be a simple change. Would you like to submit a PR for it?

UncleClapton commented 3 years ago

Sure, I'll get to work on it.