-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
async (ctx, next) => await next() #27
Conversation
What do you think about moving node's |
that's a big API change. you could always just use |
OK thanks anyway, just thought it was the right time to ask, because you are considering some more API changes. |
it returns |
@gyson oh true. it should be |
@jonathanong Nice! |
awesome |
I added a PR which should resolve the coverage issue. Additionally, I realized it's not possible to hit the |
adding 100% coverage
app.use((ctx, next) => {
throw new Error()
}) |
@gyson i agree, but when would that actually happen? |
@gyson, is |
@jonathanong |
@gyson I think I see the issue. I'll add it back with a test case that covers it. |
@smcmurray Yes. It's valid. A middleware is a function with two arguments. First The middleware function could return any value (include Promise instance) or throw exception.
This wrapped promise will be the returned promise of
Hope this helpful. Let me know if it's still confusing : ) |
I added a PR to correct my mistake. It has the |
Looks neat, You could probably avoid the extra closure (dispatch) per call by wrapping them all up front... |
adding `try... catch...` back to handle wrapped non-async cases
Does the merge of PR #29 close this? Or is there more to do? |
I want to keep this open for a little bit for feedback |
ES6+, supports this? app.use((({req, res, session}, next) => {}) Updated: |
@jonathanong What are your thoughts on including |
@calebboyd sure! |
PR welcomed until I get to it! |
Just personal opinion,
For example, app.use(async ctx => {
await ctx.next()
await ctx.next() // no idea what will happen because `.next` is changed now.
}) |
@gyson the opposite could also be said imho. That The above code could be considered a bug just as forgetting to use I think there is a TODO in for invoking next multiple times, though different from the original implementation would still be valid when setting next on the context |
About
|
Ahh nice, I added a test. Con 1 is the goal, so you've already stated you don't like it :P. Con 2 is still valid either way. Nothing will stop the user from writing incorrect code. (the side effects are different, but still there none the less). Con 3.. its really only one more way, just depends on whether or not the user chooses to use destructuring for the arguments. If this is largely unliked it doesn't have to be there... I thought I'd just toss it out, Conceptually, it makes a lot of sense to me being that the context acts like an iterator. But I'm not trying to paint the shed red by any means :) |
@jonathanong I think he was talking about #30 which I just added the same test to |
I don't think you can have both compose([
async ctx => {
await ctx.next()
await ctx.next() // it won't throw
},
async ctx => {
// do nothing
}
]) |
@calebboyd hmmm this is a good point... not sure about calling the function |
@gyson added another test. i don't see it failing. @calebboyd was trying to cherry pick your tests but couldn't give you credit :( then i forgot i had it locally and committed it lol sorry |
Thats all good it was @gyson's code |
no. please test |
@gyson great! thanks! |
not sure i'm liking |
I guess that's what we get when it's only partially an iterator :p (no |
I have some feedback based on developing a microservice last week using shan and a bunch of koa/co-related plugins. The inclusion of // example response end using ioredis
export const read = async ctx => {
const result = await ctx.redis.get(/* something */);
if (result) {
ctx.status = 200;
ctx.body = {status, result};
}
//responds with default 404 unless something threw
}; // example middleware for body validation
export const validate = async (ctx, next) => {
if (['PUT', 'POST'].includes(ctx.method)) {
// ...schema validation
ctx.assert(valid, 422, message);
}
await next(ctx);
}; |
It looks like the discussion here has wound down. As near as I can tell, the only questions left up in the air were whether context should be context or an argument, and whether next should be a property of context. context vs argumentAs I read it, there looks to be much more support for it being an argument. As far as I can tell, there's not any disagreement left on that point. next as a property of contextPros
Cons
I'd personally vote no on this issue, but it doesn't really matter to me. OtherAre there any other issues that should hold this up from moving forward? How long does it need to be open for discussion? Can we move ahead ASAP and transition koa sooner than later? |
@smcmurray sums it up :) If you guys can bring awareness to this issue and see if anyone else has any input, that would be great! I'm also not even sure if async functions have an arrow function form. We should double check that. I know Babel supports it, but I don't know if it's in the actual specs. |
I think this is the lastest. AsyncAwait and AsyncArrows |
Only concern I have is about backward compatible ( implicitly convert generator middleware to promise middleware ). //
// we can have this conversion in koa-compose, like following:
//
function compose(middleware) {
middleware = middleware.map(mw => {
if (isGeneratorFunction(mw)) {
return convertGeneratorToPromise(mw)
} else {
return mw
}
})
// ...
}
//
// or we can have conversion within koa repo, like this:
//
app.use = function (mw) {
if (isGeneratorFunction(mw)) {
mw = convertGeneratorToPromise(mw)
}
// ...
}
function convertGeneratorToPromise(genFun) {
return function (ctx, next) {
return co.call(ctx, genFun.call(ctx, createGenerator(next)));
}
}
function* createGenerator(next) {
return yield next()
} |
I prefer the conversion in koa-compose. |
I never did see any performance comparison with #30. I see @calebboyd closed #30, though. @calebboyd also backed out next as a a context property. So is support for legacy (generator) middleware the only issue left? |
I think so! On Tue, Oct 6, 2015, 10:24 AM smcmurray notifications@github.com wrote:
|
Not all middleware is chained through the 'use' method. Routers, for instance may not invoke use at all, but might invoke compose to build their own sub-chains. On the other hand, anything that does invoke 'use' also invokes compose indirectly. So converting generator middleware in compose makes more sense to me. |
Created a stand-alone lib to convert generator-based middleware to promise-based middleware. You can check it at koa-convert. |
i would rather convert to generator middleware in koa or in the router vs in compose. ideally, this would be the last version ever, and eventually koa and routers can remove generator support |
@jonathanong, wouldn't that mean that you don't have backwards-compatability out of the box? |
goal is to be able to do:
TODO:
next()
calls