(Ko)Koa, I guess

Well, well, well. Here we go, Koa.js (forge-e-et about express)

To be fair, I have no idea where this is going, bu-u-ut I have general idea to build something commerce-oriented, since it employes several important aspects of web apps: APIs integrations, forms, media and admin\manager interface. (And current out-of-box solutions kinda suck in some or other regard, so I’ll be that cool kid that ~not~ fixes everything)

First off we’ll start by installing koa itself, after that I and, I would strongly advise, you will spent some time sinking one interesting concept that (Ko)Koa brings compared to express:

Contrasting Connect’s implementation which simply passes control through series of functions until one returns, Koa invoke “downstream”, then control flows back “upstream”.
Cascading@Koa

If you’ve come from Express (or Connect for the matter) background where you have nifty little list like that:

app.use(log);
app.use(bodyparser);
app.use(multer);

You would expect to have all middleware to be executed in that order: we (setup to) log something, then fill in parsed body attached to req, then we get any files scanned and processed by multer (at least I hope that’s what this code does).

But, Koa brought back good times where you build stack of middleware – think tower of hanoi if you’re dumb and haven’t got proper CS basics – you add rings of middleware on a stick and then go through them from ground up and then back. Which was basically said in blockquote before.
(With some exceptions like some ring randomly decides to stop your careful examination by punching you with return)

So how does it look? Pretty interesting:

app.use(async (ctx, next) => {
    // start up logging 'in' and creating simple timeout promise
    console.log('in');
    const promise = new Promise(resolve =>
        console.log('Started promise') ||
            setTimeout(() =>
                console.log('Finished promise') || resolve(true), 1000
            )
    )
    // return false; //that's what I'm talking about angry rings that like to punch stuff; comment out that bad boy!
    await next(); // and now we pass the flag to next one in chain
    // we've got back to our first ring
    ctx.body = 'Flushed: ' + await promise; // and replaced body with awaited `true` from our previous `promise`
    console.log('out'); // we're outie!
})

app.use(async (ctx, next) => {
    // our next middleware, another log, another day
    console.log('setting body');
    ctx.body = require('util').inspect(ctx.req)
    // we're giving up control
    await next()
    // and receiving it right back since there's no more middleware
    console.log('out second')
    // our function ends and automatically resolves promise since it's an async one
})

By the way, if you aren’t familiar with modern JS ~callbacks~ I-I mean async-await ~promises~, GET OUT WHILE YOU STILL CAN!, cause it’ll be a proper ass blasting until you understand that every async function returns promise and await lets you to get then (resolved value) out of it.

So, what does it returns? As you should expect:

in
Started promise
setting body
out second
// wait a second
Finished promise
out

If you got the order wrong.. well, not like I can help you, but reiterate:
Koa calls each used middleware in the order you attached them, then when one finally returns (or there is nowhere else to run) it gets back through whole chain, executing anything after await-ed next(). If you have done some skinny dipping in asynchronous JS you’ll notice that it reminds of something, something generat-ed.. yas, Koa does little bit of gene.. khem doesn’t seem to be the case anymore.

Also as you may have noticed, middleware is littered with ES6 (or 7?) stuff like async-await, which you technically can ditch (I think so at least), which we can test right now:

app.use((ctx, next) => {
    console.log('in');
    const promise = new Promise(resolve =>
        console.log('Started promise') ||
            setTimeout(() =>
                console.log('Finished promise') || resolve(true), 1000
            )
    )
    return next()
        .then(() => promise)
        .then(promiseVal => {
            ctx.body = 'Flushed: ' + promiseVal;
            console.log('out');
        })
    // await next();
})

Other midleware function stayed the same and whole code produced same logging output (thinking about it, I guess I could have just appended it to body, bu-u-ut):

in
Started promise
setting body
out second
Finished promise
out

Which should again be of no surprise – async await after all is mostly cool syntatic sugar over combo of promises and generators. I.e. each await is just then-ned promise neatly unwrapped into “regular” variable. (On the surface that is, I would hapilly guess that there are some sheganigans with generator’s next-ing going on)

So.. where are we? I think I’ve been describing how to set up our cute and tasty (Ko)Koa, and I also think that’s enough for today.
I’ll be checking out router next and probably mapping out wtf we’re going to do with this.

nil commento load