When it comes to Node.js development, express and KOA are two big frameworks that are hot right now. Express has been around for some time and is a concise and flexible Web development framework that is simple to use and powerful. Koa is a relatively young, agile framework that has been redeveloped by the original Express framework team based on the new ES6 features, and is now poised to overtake Express.

Express and KOA are both server-side development frameworks. Server-side development focuses on the encapsulation and processing of HTTP Request and HTTP Response objects, application life cycle maintenance, and view processing. The following will be mainly through these aspects, a comparative introduction of the two, to see what the difference is.

Express is mainly based on the Connect middleware framework, which is rich in functionality and can be used on demand, and the framework itself encapsulates a lot of convenient functions, such as routing, view processing, and so on. Koa is mainly based on CO middleware framework. The framework itself does not integrate too many functions, and most of the functions need to be solved by the user require middleware. However, due to its middleware mechanism based on ES6 Generator, it solves the problem of “callback hell” and troublesome error handling for a long time. Very popular with developers.

First impressions of Express and KOA

Hello World

//Express var Express = require(' Express ') var app = Express () app.get('/', function (req, res) { res.send('Hello World! ')}); // Start the service app.listen(3000);Copy the code

//Koa var koa = require('koa'); var route = require('koa-route'); Var app = koa(); // Create an APP instance // create a get request route to the root of the project, and output the string Hello World! Use (route.get('/', function *(){this.body = 'Hello World'; })); // Start the service app.listen(3000);Copy the code

As you can see, both are simple enough to create a basic Web service in a few lines of code. They are also written in much the same way, with the biggest difference being that routing processing Express is self-integrated, whereas KOA requires middleware to be introduced. Here is a comparison of the two features in the official Koa documentation:

A comparison of important functions

Feature Koa Express Connect
Middleware Kernel
Routing
Templating
Sending Files
JSONP

Through the subsequent comparison, you can actually see that although KOA looks less integrated than Express, it is basically the same in use, because the middleware is very rich and comprehensive, all you need to do is require it (not necessarily require it like Express). It’s more flexible to use.

Application lifecycle and context

During projects, we often need configuration and data objects that are shared throughout the application lifecycle, such as service urls, whether or not a feature is enabled, interface configuration, and currently logged user data. Both are very convenient. Koa’s Application Context feels a little easier to use.

//Express // share configuration, Express provides many convenient methods app.set('enableCache', true) app.get('enableCache')//true app.disable('cache') app.disabled('cache')//true app.enable('cache') App. enabled('cache')//true // Application sharing data: app.locals app.locals. User = {name:"Samoay", id:1234};Copy the code

//Koa // App. enableCache = true; app.use(function *(next){ console.log(this.app.enableCache); //true this.app.enableCache = false; //just use this this.staticPath = 'static'; yield *next; }); State this.state.user = {name:"Samoay", id:1234};Copy the code

Request the HTTP Request

What the server needs to do, how it needs to do it, and the parameters it needs to process depend on the Request sent by the client. Both frameworks encapsulate HTTP Request objects to facilitate the processing of this part. The following examples illustrate the processing of request parameters. For other information, such as headers and cookies, please refer to the official documents. There’s not much difference between the two except for the way they’re written. GET parameters can be obtained directly from the Request object. POST parameters need to be parsed and then evaluated by the middleware.

// Express // QueryString parameters // GET /shoes? Order =desc&shoe[color]=blue req.query.order // => "desc" req.query.shoe.color // => "blue" // Obtain Restful URL parameters through the route app.get('/user/:id? ', function userIdHandler(req, res) { console.log(req.params.id); res.send('GET'); Var bodyParser = require('body-parser'); app.use(bodyParser.urlencoded({ extended: true })); app.post('/', function (req, res) { console.log(req.body); res.json(req.body); })Copy the code

// GET /? action=delete&id=1234 this.request.query // => { action: 'delete', id: Var route = require('koa-route'); app.use(route.get('/post/:id', function *(id){ console.log(id); / / = > 1234})); // Get POST data: co-body middleware is required // Content-type: application/x-www-form-urlencoded // title=Test&content=This+is+a+test+post var parse = require('co-body'); app.use(route.post('/post/new', function *(){ var post = yield parse(this.request); //this console.log(post); // => { title: 'Test', content: 'This is a test post' } }));Copy the code

Routing the Route

After receiving a request from a client, the service identifies the request using HTTP Method: GET, POST, PUT… And the specific path of the request. This part of the function is what the Route needs to do, which is basically distribute the request to different callback methods to handle.

App. all('*', authentication, loadUser); // Express // app.all('*', authentication, loadUser); // App. all('*', requireAuthentication) app.all('*', loadUser); App.all ('/ API /*', requireAuthentication); App. get('/user/:id', function(req, res) {res.send('user '+ req.params.id); // app.get('/user/:id', function(req, res) {res.send('user' + req.params.id); }); App. post('/user/create', function(req, res) {res.send('create new user'); // app.post('/user/create', function(req, res) {res.send('create new user'); });Copy the code

There are two things to note here. The first is app.get. There is also an app.get method in the application lifecycle that gets the project configuration. Express is a common method inside. If only one parameter is passed in, the configuration is obtained, and the two parameters are treated as routes. App. use(‘*’, cb) and app.all(‘*’, cb), the former is middleware mode, the call is sequential, not necessarily executed; The latter is the routing method, which will definitely be implemented.


Var route = require('koa-route'); Use (route.get('/', list)); app.use(route.get('/post/new', add)); app.use(route.get('/post/:id', show)); app.use(route.post('/post', create)); Var router = require('koa-router')(); router.get('/', list) .get('/post/new', add) .get('/post/:id', show) .post('/post', create); app.use(router.routes()) .use(router.allowedMethods());Copy the code

The view Views

The Express framework itself integrates view functionality, provides consolidated.js, can have almost any Javascript template engine, and provides a convenient way to set up views. Koa needs to introduce co-views middleware, and co-views is also based on consolidated. Js, which has the same powerful support capability.

Set ('views', __dirname + '/ TPLS '); app.set('view engine', 'html'); // By default, Express automatically selects templates based on the suffix template // engine rendering, jade and EJS support. App. engine(' HTML ', require('ejs').renderfile); // If the template engine does not support (path, options, callback) var engines = require('consolidate'); app.engine('html', engines.handlebars); app.engine('tpl', engines.underscore); app.get('list', function(res, req){ res.render('list', {data}); });Copy the code

Var views = require('co-views'); Var render = views(' TPLS ', {map: {HTML: 'swig'},// var userInfo = { name: 'tobi', species: 'ferret' }; var html; html = render('user', { user: userInfo }); html = render('user.jade', { user: userInfo }); html = render('user.ejs', { user: userInfo });Copy the code

Returns the HTTP Response

With the request parameters taken, the specific request processed, and the view ready, it’s time to return to the client, which is the HTTP Response object. This part is also part of the framework’s base, and it is all wrapped. The notable difference is that KOA binds the output directly to the ctx.body property, and the output of JSON or JSONP requires middleware.

// Express // output plain HTML res.render('tplName', {data}); JSON res.jsonp({user: 'Samoay'}); // => {"user": "Samoay"} callback=foo res.jsonp({ user: 'Samoay' }); // => foo({ "user": "Samoay" }); //res.send([body]); res.send(new Buffer('whoop')); res.send({ some: 'json' }); res.send('<p>some html</p>'); // Set the HTTP Status code res.status(200);Copy the code

Use (route.get('/post/update/:id', function *(id){this.status = 404; this.body = 'Page Not Found'; })); var views = require('co-views'); Var render = views(' TPLS ', {default: "jade"//render); app.use(route.get('/post/:id', function *(id){ var post = getPost(id); this.status = 200; //by default, optional this.body = yield render('user', post); })); //JSON var json = require('koa-json'); app.use(route.get('/post/:id', function *(id){ this.body = {id:1234, title:"Test post", content:"..." }; }));Copy the code

Middleware Middleware

Compared the use of several main framework functions, in fact, the biggest difference, the most different way of use is in the processing of middleware. Because Express predates ES6, middleware is based on callback. Koa, on the other hand, benefits from generator features and the CO framework (which encapsulates all generator returns as Promise objects), making middleware more elegant to write.

// Req is used to get the request information, ServerRequest instance // res is used to respond to the result of processing, ServerResponse instance // next() is used to transfer the current control to the next processing, Var x = function (req, res, next) {return next(); // Pass an error message to the next middleware return next(err); Return res.send('show page'); };Copy the code

// koa everything on the CTX object +generator app.use(function *(){this; // is the Context this.request; // is a koa Request this.response; // is a koa Response this.req; // is node js request this.res; // is node js response // });Copy the code


Author: Jin Hong