Express/koa/hapi
This article is translated from:
Https://www.airpair.com/node.js/posts/nodejs-framework-comparison-express-koa-hapi
1. Introduction
Until today, Express.js is still the most popular node. JS Web application framework. It seems to have gradually become the underlying framework for most node. js Web applications, including many popular frameworks, such as Sail.js, which are built on express.js. But now we have more "Class Sinatra"(note: Sinatra is a ruby framework, the code is very concise, claiming to develop a blog project requires only 100 lines of code) like the framework can be selected. The next step is to introduce the KOA and HAPI two frames respectively.
The purpose of this article is not to persuade you to use any of these frameworks, but rather to help you compare and analyze the pros and cons of these three frameworks.
2. Frame background
The three frameworks we are comparing today have many similarities. For example, they can create a service in a few lines of code, and the rest API development is a piece of cake. Let's look at these three frames separately.
2.1. Express
June 26, 2009, TJ Holowaychuk first submitted the code for Express. On January 2, 2010, Express officially released the 0.0.1 version, and by that time, the author has submitted more than 660 code. At that time, the two main development maintainers of Express were TJ and Ciaron Jessup respectively. At the time of the first release, Express described this framework in the README.MD introduction file of GitHub:
a fast and Minimalist JS Server development framework based on node. JS and the Chrome V8 engine.
Today, more than 5 years later, Express has been released to 4.10.1, submitted more than 4,925 code, currently mainly using strongloop for development and maintenance, because TJ classmate has been transferred to the go language development community.
2.2, Koa
KOA was a year ago on August 17, 2013 by TJ classmate (yes, or he ...). ) The first commit code. That's what he described as Koa: "More expressive, more robust node. JS middleware." The CO component-based generators handles asynchronous callbacks, and your code will become more elegant, whether it's a Web application or rest API development. (Note: After the release of KOA2, the introduction of the Co component has been abandoned, but the asynchronous callback is processed using the ES7 async/await syntax). Lightweight KOA claims no more than 400 lines of code. (Note: Sloc is the number of source lines, divided into physical code lines, loc, and the number of logical code lines lloc). as of now, KOA has released 0.13.0 version, more than 585 code submissions.
2.3, Hapi
HAPI was first submitted by Eran Hammer, a student from Wal-Mart Labs, on August 5, 2011. Originally he was just a postmile(This is a collaboration list tool developed on node. JS, the service driven by Hapi complete ) a core component, also based on express development. Later Hapi was independent as a framework for the development and maintenance, Eran students in his blog said:
"The core idea of HAPI is that the configuration is better than the code, so the business code must be stripped out of the transport layer."
So far, HAPI has submitted more than 3,816 code, and the version is 7.2.0, which is still being maintained by Eran Hammer for major development.
OK, finally let's take a look at the community stats to see how active these three frameworks are:
Reference items |
Express.js |
Koa.js |
Hapi.js |
GitHub Points of Praise |
16158 |
5846 |
3283 |
Code Contributors |
163 |
49 |
95 |
Number of dependent packages |
3828 |
99 |
102 |
StackOverflow Number of questions |
11419 |
72 |
82 |
3. Create a service
Basically, the first step for every developer who has just started to contact node. JS is to create a service. Because below we will use each frame in turn to create a service separately to see similarities and differences between them.
3.1. Express
var express = require (' Express '); var app = Express (); var server = App.listen (+, function () { console.log (' Express I S listening to http://localhost:3000 ');});
The above operation should be very skilled for most node developers. Let's first introduce express and then create an instance object and assign it to the variable app. The next step is to instantiate a service and start listening on Port 3000. App.listen () is in fact a layer of encapsulation of the native Http.createserver () Nodejs.
3.2, Koa
var = require (' KOA '), var app = Koa (), var server = App.listen (KOA, function () { console.log (' KOA ' listening to H ttp://localhost:3000 ');});
Obviously, KOA's syntax is very similar to express. In fact, you just need to change the introduction of express to introduce KOA. Similarly, App.listen () also has a layer of encapsulation for http.createserver ().
3.3, Hapi
var = require (' Hapi '), var server = new Hapi.server (HAPI), Server.start (function () { Console.log (' Hapi is Listening to http://localhost:3000 ');});
Hapi's syntax is a little more special. However, the first step is to introduce HAPI, but this is instantiated in a HAPI app variable, and then you can create a service for the specified port. In Express and KOA This step we get is a callback function, but Hapi returns a server object. Once we call this service on Port 3000 via Server.start (), he will return a callback function. Then, unlike KOA and express, this callback is not for HTTP. Createserver () is a layer of encapsulation, but the logic of HAPI itself.
4. Routing
Next we continue to understand the important function of being a service, which is routing. The first step is to use each framework to create a "Hello World" app, and then continue to focus on some of the more useful features of the REST API.
4.1 Hello World
4.1.1 Express
var express = require (' Express '); var app = Express (); App.get ('/', function (req, res) { res.send (' Hello World ');}); var Server = App.listen (+, function () { Console.log (' Express is listening to http://localhost:3000 ');});
We use the Get () method to capture a "get/" request, and then call a callback function to handle the request, which has two parameters: req and res. In this example we only use the Res.send () method of res to return a string to the page. Express contains a number of built-in methods to handle routing functions. Here are a few of the methods that are commonly used in express (only partial, not all): Get, post, put, head, delete ...
4.1.2 Koa
var koa = require (' KOA '); var app = Koa (); App.use (function * () { this.body = ' Hello world ';}); var server = App.listen (, function () { Console.log (' Koa is listening to http://localhost:3000 ');});
Koa and express are slightly different because he uses ES6 's generators grammar. (Note: Generators is a workaround for asynchronous callbacks proposed by ES6, which will be promoted directly to async/await in ES7) by adding a * before the method to indicate that the method returns a Generator object. The purpose of the generators function is to make the asynchronous function produce some synchronous values, but these values are still in the current request scope. (note: Generator defines a different state value through yield, and return is a status value.) Learn more:http://es6.ruanyifeng.com/#docs/generator ) in App.use (), the generator function assigns a value to the response body. The This object in KOA is actually the encapsulation of node's request with the response object. This.body is a method of responding to a body object in KOA. It can basically be assigned any value, string, buffer, data stream, object, or null. KOA Core Library provides a lot of middleware, here we just use one of them, this middleware can capture all the routes, and then respond to a string.
4.1.3 Hapi
var = require (' Hapi '), var server = new Hapi.server (HAPI), Server.route ({ method: ' GET ', path: '/', Handler:function (Request, Reply) { reply (' Hello world '); }}); Server.start (function () { Console.log (' Hapi is listening to http://localhost:3000 ');});
Here we use a built-in method provided by the server object: Server.route (), which requires these parameters: path (required), method (required), Vhost, and handler (required). This HTTP method can handle all of our common get/put/post/delete requests, or we can use * to handle all routing requests. The callback function is passed HAPI by default to the request object and the reply method, reply is the method that must be executed, and it is necessary to pass in a data that can be a string, a serialized object, or a stream.
4.2 REST API
The Hello World program has never had much expectation, as it can only show the simplest and most basic operations for creating and running an application. The REST API is a feature that is necessary for almost all large applications, and is a great help for us to better understand these frameworks. So next we'll look at how these frameworks handle the rest API.
4.2.1 Express
var express = require (' Express '); var app = Express (); var router = Express. Router (); REST apirouter.route ('/items '). Get (function (req, res, next) { res.send (' Get ');}). Post (function (req, res, next) { res.send (' Post ');}); Router.route ('/items/:id '). Get (function (req, res, next) { res.send (' Get ID: ' + req.params.id) '). Put (function (req, res, next) { res.send (' Put ID: ' + req.params.id);}). Delete (function (req, res, next) { res.send (' Delete ID: ' + req.params.id);}); App.use ('/api ', router);//Indexapp.get ('/', function (req, res) { res.send (' Hello World ');}); var Server = App.listen (+, function () { Console.log (' Express is listening to http://localhost:3000 ');});
We added the rest API to the existing Hello World program. Express provides a number of abbreviated ways to handle routing. This is the version of the Express 4.x syntax, in fact, the same as the Express 3.x version, also hope you no longer use Express. Router () method, instead of replacing the new API:app.use ('/api ', Router). The new API allows us to replace the previous router.route () with App.route (), of course adding a descriptive verb/ API. This is a good modification, because it reduces the chance for developers to make mistakes, and makes a minimal modification to the original HTTP method.
4.2.2 Koa
var koa = require (' KOA '); var route = require (' Koa-route '); var app = Koa ();//REST Apiapp.use (Route.get ('/api/items ', funct ion* () { this.body = ' Get ';}); App.use (Route.get ('/api/items/:id ', function* (ID) { this.body = ' Get ID: ' + ID;})); App.use (Route.post ('/api/items ', function* () { this.body = ' post ';})); App.use (Route.put ('/api/items/:id ', function* (ID) { this.body = ' Put ID: ' + ID;})); App.use (Route.delete ('/api/items/:id ', function* (ID) { this.body = ' Delete ID: ' + ID;})); /All other routesapp.use (function * () { this.body = ' Hello world ';}); var server = App.listen (, function () { Console.log (' Koa is listening to http://localhost:3000 ');});
Obviously, KOA is not able to reduce the repetition of the route verb as express does. It also requires the introduction of a separate middleware to handle routing. I chose to use Koa-route because he was primarily developed and maintained by the KOA team, and of course there are many other developer-contributed routing middleware to choose from. From the keyword of the method name, Koa's Routing and express are very similar, for example. Get (),. put (),. Post (), and. Delete ().
KOA has an advantage in handling routing, which uses the ES6 generator function, which reduces the complexity of the callback function.
4.2.3 Hapi
var Hapi = require (' Hapi '); var server = new Hapi.server; Server.route ([{method: ' GET ', path: '/api/item S ', handler:function (request, Reply) {reply (' Get item id '); }}, {method: ' Get ', Path: '/api/items/{id} ', handler:function (request, Reply) {reply (' Get item ID: ' + Request.params.id); }}, {method: ' Post ', Path: '/api/items ', handler:function (request, Reply) {reply (' Post item '); }}, {method: ' Put ', Path: '/api/items/{id} ', handler:function (request, Reply) {reply (' Put item ID: ' + Request.params.id); }}, {method: ' delete ', path: '/api/items/{id} ', handler:function (request, Reply) {reply (' Delete item I D: ' + request.params.id); }}, {method: ' GET ', Path: '/', handler:function (request, Reply) {reply (' Hello world '); }}]); Server.start (function () {Console.log (' Hapi is listening to http://localhost:3000 ');});
Compared to other frameworks, Hapi's routing configuration gives the first impression that the code is crisp and readable. Even the required configuration parameters Method,path,hanlder and reply are easily distinguishable. As with KOA, the code for the Hapi route is more repetitive, so the odds of error are also greater. All of this is because Hapi prefer to use configuration to complete routing, so our code will be cleaner and easier to maintain within the group. Hapi also tries to improve the ability to handle code errors, because sometimes he doesn't even need developers to write any code (note: It means that the configuration is completely implemented, and the callback function is also used by default.) The probability of this error is much smaller and easier to get startedwith. If you attempt to access a route that is not defined in the rest API, HAPI will return a JSON object that contains the status value and error information.
5. Advantages and Disadvantages
5.1 Express
5.1.1 Advantages
Express has the largest community, rather than just the three frameworks, but for all the NODEJS framework is also the largest. For now, he is the most mature framework of the three, close to 5 years of development investment, while also using Strongloop(Note: Strongloop is a process management tool that provides the CLI and UI interface. ) to manage the code on the online warehouse. He provides an easy way to create and run a service, while the built-in routing also makes the code reusable.
5.1.2 Disadvantages
In the process of using express, we often have to deal with a lot of tedious tasks. For example, he does not have a built-in error-handling mechanism, and there are many middleware options for the same problem, which makes it easy for developers to get lost in the middleware choice, in short, a problem you will have n multiple solutions. Express claims to be a configurable option, which is not good or bad, but it is a disadvantage for a developer who has just contacted Express. In addition, there is a big gap between express and other frameworks.
5.2 Koa
5.2.1 Advantages
A small step forward in KOA is that his code is more expressive, and developing middleware is much easier than other frameworks. KOA is a very basic quasi-system framework, and developers can choose (or develop) the middleware they need, rather than choosing Express or HAPI middleware. He is also the only one of the three actively embracing the ES6 framework, such as the use of the ES6 generators function.
5.2.2 Disadvantages
At present, KOA is still in the unstable version, still in the development stage. Using ES6 for development is indeed at the leading level, such as KOA needs to run on a version of Nodejs 0.11.9 or more, while the current Nodejs text version is 0.10.33. This is something that can be counted as good or bad, just like the express developers have a lot of middleware to choose and even develop their own middleware. For example, as we see above, there is a lot of middleware for routing to choose from.
5.3 Hapi
5.3.1 Advantages
Hapi has always been proud to say that their framework is better than the code, and of course there are many developers who might question this as an advantage. But this is true for large project groups, where code consistency and code reusability can be maintained. In addition, the framework is supported by Wal-Mart Labs, and many big companies are using HAPI online to show that he has passed tough tests because the companies will consider more before they use HAPI to run their projects. All these indications, therefore, suggest that HAPI is developing towards a great framework.
5.3.2 Disadvantages
Hapi's positioning is more prone to large or complex applications. For a simple application, Hapi in the code is somewhat redundant, and the current HAPI provides a few sample programs, using HAPI to develop open source applications are also very few. Therefore, if you choose Hapi, you may want to devote more effort to development, rather than simply invoking a third-party middleware.
6. Summary
We've looked at three frames, which is pretty good. Some representative sample code. Express is still the most popular and well-known frame of the moment. When starting a new development project, perhaps the first response is to use Express to create a service. But now I would like to think more about using KOA or HAPI. KOA actively embraced ES6 's grammar, demonstrating the true charm of promise. At present, the entire Web development community is aware of the advantages of ES6, is gradually migrating above. Hapi should be the first choice for large project groups or large projects. The fact that the configuration he advocates is better than the code will benefit the project team in the repetition of the code, which is what most project teams are aiming for. Now move on, try a new frame, maybe you'll like him or hate him, but if you don't try you'll never know what the outcome is, and ultimately all of these experiences will make you a better developer.
Express/koa/hapi