Code odyssey : Express
Recently I was looking for web frameworks on Node.js. There are Tower.js, Railway, GeddyJS, SocektStream, Meteor and lots of cool framework on Node.js. However, Express, which created in the beginning of Node.js era, is still a very stable and easy to use framework with the most plugin and community support. Therefore, I think it is a good candidate as my 2nd source code review project.
Express.js is developed by TJ Holowaychuk, who rebuild the web development on Node.js with express, jade, mocha, stylus and more. Express is inspired by the simple of Sinatra provide a simple and elegant interface for http request, also with connect middle support that let user can easily extend the framework.
Usage
Here’s the hello world sample of express. It assign a callback for get request on root ‘/‘, and start the server to listen port 3000. More example can be found on express/examples and Documentation of express.
1 |
|
Connect
Express is using the Connect Middleware. But What is connect? From the configuation function of Express:
1 |
|
We can see that express call the use method with connect.query(), the query() parse the query string and attach to the request object req.query.
In the source of connect.query():
1 |
|
The next() method invoke the next method on the process chain.
We can see that it return a method that parse the req.url with qs.parse function and return to req.query. So we can get the query string from req.query in our application.
So we can see the middleware as a function that execute before the request and add functionality to (req, res) object. So we can easily use a function as middleware. In example, we can refactor the hello world as middleware:
1 |
|
In more advance usage, we can build a flash message using middleware:
1 |
|
Also, there is another kind middleware called param callback. which will only be executed when the route have the param key:
1 |
|
Will be invoked when route params have ‘user_id’:
1 |
|
Application
The main application is on lib/express.js. It produce express app by createApplication function. First, the application merge with connect, set request and response object, than call the initialize function of application defined in lib/application.js
1 |
|
In application.js, the init function initialize the settings and default configuration of express, and also load the Router to route the Http requests.
Also an important part, some of the settings is depend on process.env, like cache. Which can be enabled by exports NODE_ENV=production.
this.set('env', process.env.NODE_ENV || 'development');
Router
Lets step into the router, basically, the router provide route method to assign function to route, and matchRequest to return route.
In route
1 | /** |
The route function take the Http method (like ‘get’), path and callback. normalize them and create Route object. add to the map[method] array in Router.
Also, it use the meta programming skill to generate public helper for user, so we can call the app.get or app.post method to assign route.
In application.js
1 | var methods = require('methods') |
But after the route is set, how do express invoke the handle function? We can see the usage from the test case:
1 | describe('.middleware', function(){ |
In the test case we can see the app.use(router.middleware) mount the routes to the application. In router.middleware, it call the _dispatch(req, res, next) function,
it call the route.matchRequest method to get the matched route, handle param callback and execute the callback chain:
1 |
|
Request / Response
Request and Response object in express is inheritate http.IncomingMessage and http.ServerResponse from node. Request provide helpers for http header, content-type, URL and param parsing.
Response is providing helpers for status and results too. Also provide the send function from ‘response-send’ module. Which detect response type and set corresponding content-type.
View
In the lib/view.js, the main functions is render and lookup, which find the template and call the render function on engine. The render function on app initialize new View, the view set the lookup(name) to path, and call the view.render method to return result:
1 |
|
in the app.render:
1 |
|
MVC example
In the examples/mvc directory, it shows you how to structure a mvc style application in express.
1 |
|
The followed structure is a sample of mvc in express, the index.js load the boot.js, which mount all the routes under controllers/ in a RESTful style. And set the views path and static path.
There are no restriction on how to build the structure of express application. The Railway is one of the example that it extend express to be a Rails like Mvc application.
Conclusion
Express is a lightweight web framework and it is a good entry point to know how to build a web framework in Node.js. Hope this walkthrough can help you understand how express work. And can be more comfortable with new framework like meteor.
Also it is a well styled and documented project, so when you find some problem in developing express application, don’t be hesitate to use the source code (luke!) and the Guide of Express
Comments