Koa v2 introduces a new signature for middleware.
Old signature middleware (v1.x) support will be removed in v3
The new middleware signature is:
// uses async arrow functions
app.use(async (ctx, next) => {
try {
await next() // next is now a function
} catch (err) {
ctx.body = { message: err.message }
ctx.status = err.status || 500
}
})
app.use(async ctx => {
const user = await User.getById(this.session.userid) // await instead of yield
ctx.body = user // ctx instead of this
})
You don't have to use asynchronous functions - you just have to pass a function that returns a promise. A regular function that returns a promise works too!
The signature has changed to pass Context
via an explicit parameter, ctx
above, instead of via
this
. The context passing change makes koa more compatible with es6 arrow functions, which capture this
.
Koa v2.x will try to convert legacy signature, generator middleware on app.use
, using koa-convert.
It is however recommended that you choose to migrate all v1.x middleware as soon as possible.
// Koa will convert
app.use(function *(next) {
const start = Date.now();
yield next;
const ms = Date.now() - start;
console.log(`${this.method} ${this.url} - ${ms}ms`);
});
You could do it manually as well, in which case Koa will not convert.
const convert = require('koa-convert');
app.use(convert(function *(next) {
const start = Date.now();
yield next;
const ms = Date.now() - start;
console.log(`${this.method} ${this.url} - ${ms}ms`);
}));
You will have to convert your generators to async functions with the new middleware signature:
app.use(async (ctx, next) => {
const user = await Users.getById(this.session.user_id);
await next();
ctx.body = { message: 'some message' };
})
Upgrading your middleware may require some work. One migration path is to update them one-by-one.
- Wrap all your current middleware in
koa-convert
- Test
npm outdated
to see which koa middleware is outdated- Update one outdated middleware, remove using
koa-convert
- Test
- Repeat steps 3-5 until you're done
You should start refactoring your code now to ease migrating to Koa v2:
- Return promises everywhere!
- Do not use
yield*
- Do not use
yield {}
oryield []
.- Convert
yield []
intoyield Promise.all([])
- Convert
yield {}
intoyield Bluebird.props({})
- Convert
You could also refactor your logic outside of Koa middleware functions. Create functions like
function* someLogic(ctx) {}
and call it in your middleware as
const result = yield someLogic(this)
.
Not using this
will help migrations to the new middleware signature, which does not use this
.
In v1.x, the Application constructor function could be called directly, without new
to
instantiate an instance of an application. For example:
var koa = require('koa');
var app = module.exports = koa();
v2.x uses es6 classes which require the new
keyword to be used.
var koa = require('koa');
var app = module.exports = new koa();
An explicit check for the test
environment was removed from error handling.
- co is no longer bundled with Koa. Require or import it directly.
- composition is no longer used and deprecated.
The v1.x branch is still supported but should not receive feature updates. Except for this migration guide, documentation will target the latest version.
If you encounter migration related issues not covered by this migration guide, please consider submitting a documentation pull request.