shan v0.0.5
shan
koa with Promise-based middleware
Installation
$ npm install shanUsage
You may need babel-node to run following code (for async arrow function).
const shan = require('shan')
const favicon = require('koa-favicon')
let app = shan()
app.useKoa(favicon())
app.use(async (ctx, next) => {
let start = Date.now()
await next(ctx)
ctx.response.set('X-Response-Time', (Date.now() - start) + 'ms')
})
app.use(ctx => {
ctx.response.body = 'hello'
})
app.listen(4321)About
This is an application inherits from koa but override app.use to accept promise-based middleware instead of generator-based middleware.
Promise-based Middleware
Promise-based middleware is a function with two arguments, ctx and next, and return a any or Promise<any>.
If any is returned, it will be wrapped to Promise using Promise.resolve(value). If there is any exception, the
error will be wrapped to Promise using Promise.reject(error).
ctxis just instance of KoaContext.nextcontains info about next middleware. To invoke next middleware, just callnext(ctx). It will return aPromise<any>result from next middleware.
// ctx: KoaContext
// next: (KoaContext) => Promise<any>
app.use((ctx, next) => {
console.log(1)
return next(ctx).then(() => {
console.log(8)
})
})
// use async arrow function, may need help from babel
app.use(async (ctx, next) => {
console.log(2)
await next(ctx)
console.log(7)
})
// use co
app.use(co.wrap(function* (ctx, next) {
console.log(3)
yield next(ctx)
console.log(6)
}))
// use bluebird
app.use(Bluebird.coroutine(function* (ctx, next) {
console.log(4)
yield next(ctx)
console.log(5)
}))Utility Middleware
A few utility middleware are included for convenience.
Koa Converter Middleware
Convert koa generator-based middleware to promise-based middleware.
You can use any generator-based middleware from koa ecosystem.
app.useKoa(require('koa-favicon')())
app.useKoa(function* (next) {
// ...
yield next
})Logger Middleware
Print request message to console when it flows through.
app.useLogger(ctx => `> ${ctx.method} ${ctx.path}`)
// it's equivalent to
app.use((ctx, next) => {
console.log(`> ${ctx.method} ${ctx.path}`)
return next(ctx)
})Router Middleware
Simple router with fluent interface.
app.useRouter(it => it
.get('/', (ctx, next) => {
})
.post('/signup', (ctx, next) => {
})
.all('/repos/:id', (ctx, next) => {
})
.route('/users/:id', {
get: (ctx, next) => {
},
post: (ctx, next) => {
},
delete: (ctx, next) => {
}
})
)Tracer Middleware
Profiling time spent within in one or multiple middleware.
app.useTracer('name1')
app.use(async (ctx, next) => {
await sleep(100)
await next(ctx)
await sleep(400)
})
app.useTracer('name2')
app.use(async (ctx, next) => {
await sleep(200)
await next(ctx)
await sleep(300)
})
app.useTracer('name3')It will provide info like following:
name1 | +0 | +403.419
name2 | +102.017 | +305.734
name3 | +202.964 | +0.449 Try Middleware
Shortcut for try...catch...finally.
app.useTry({
catch(ctx, err) {
// catch block
},
finally(ctx) {
// finally block
}
})
// it's equivalent to
app.use(async (ctx, next) => {
try {
await next(ctx)
}
catch (err) {
// catch block
}
finally {
// finally block
}
})License
MIT