hello koa

Posted by 鸿杰 on February 17, 2016

NodeJS平台上最热门的框架莫非express了,但是似乎没有用到es6中的优势语法,于是express团队又搞了一个叫koa的框架,支持es6,所以长远地看,选择koa才是王道。

对于我这样一个很少写js的人来说,一上手就开始使用koa,其实学习难度的曲线挺陡峭的,那再陡峭也得往上爬啊。。。

首先和koa认识一下,从这篇文档中我们可以大致了解到koa是一个极简的框架,连路由的功能都需要借助于第三方中间件。啥叫中间件?我目前的理解就是一个功能插件。使用koa-generator来新建一个项目试试看。

项目建好之后,打开项目根目录下的app.js:

var app = require('koa')()
	// 导入中间件
	, koa = require('koa-router')()
	, logger = require('koa-logger')
	, json = require('koa-json')
	, views = require('koa-views')
	, onerror = require('koa-onerror');

// 路由
var index = require('./routes/index');
var users = require('./routes/users');

// 设置views的目录和所使用的模板
app.use(views('views', {
	root: __dirname + '/views',
	default: 'jade'
}));
// 加入解析post请求中body的中间件
app.use(require('koa-bodyparser')());
// 加入解析json的中间件
app.use(json());
// 加入log记录的中间件
app.use(logger());

// 收到请求时,先执行这个generator方法
app.use(function *(next){
	// 记录开始的时间
	var start = new Date;
	// 挂起并执行next
	yield next;
	// 执行完next继续执行,记录耗时并打印
	var ms = new Date - start;
	console.log('%s %s - %s', this.method, this.url, ms);
});

// 设置静态资源目录
app.use(require('koa-static')(__dirname + '/public'));

// 定义路由
koa.use('/', index.routes(), index.allowedMethods());
koa.use('/users', users.routes(), users.allowedMethods());

// 使路由生效
app.use(koa.routes());

// 监听错误
app.on('error', function(err, ctx){
	log.error('server error', err, ctx);
});

module.exports = app;

稍微做了一些注释,可以看到app.js中都是项目设置的逻辑。

首先看看路由功能。

先将路由类导入

// 路由
var index = require('./routes/index');
var users = require('./routes/users');

然后定义路由

// 定义路由
koa.use('/', index.routes(), index.allowedMethods());
koa.use('/users', users.routes(), users.allowedMethods());

// 使路由生效
app.use(koa.routes());

此时我们访问127.0.0.1:3000就路由到了./routes/index中,访问127.0.0.1:3000/users就路由到了./routes/users中了。

打开./routes/users.js:

var router = require('koa-router')();

router.get('/', function *(next) {
	this.body = 'this a users response!';
});

module.exports = router;

发现router.get方法的第一个参数是’/’,那么是否意味着get的第一个参数中可以省去’/users’?做个实验:

将users.js中改为:

var router = require('koa-router')();

router.get('/', function *(next) {
	this.body = 'this a users response!';
});

router.get('/test', function *(next) {
	this.body = 'this a users test response!';
});

module.exports = router;

访问127.0.0.1:3000/users/test,浏览器中显示this a users test response!。bingo。

那么前面的猜想被证实了,那路由的逻辑我们就可以新建一个js来实现,而不需要修改app.js代码,如此整体的项目结构也就清晰了。

在app.js中加入当前项目的路由类:test.js

var app = require('koa')()
	// 导入中间件
	, koa = require('koa-router')()
	, logger = require('koa-logger')
	, json = require('koa-json')
	, views = require('koa-views')
	, onerror = require('koa-onerror');

// 路由
var index = require('./routes/index');
var users = require('./routes/users');
var test = require('./routes/test');

// db
var db = require('./app/models/db/db');

// 设置views的目录和所使用的模板
app.use(views('views', {
	root: __dirname + '/views',
	default: 'jade'
}));
// 加入解析post请求中body的中间件
app.use(require('koa-bodyparser')());
// 加入解析json的中间件
app.use(json());
// 加入log记录的中间件
app.use(logger());

// 收到请求时,先执行这个generator方法
app.use(function *(next){
	// 记录开始的时间
	var start = new Date;
	// 挂起并执行next
	yield next;
	// 执行完next继续执行,记录耗时并打印
	var ms = new Date - start;
	console.log('%s %s - %s', this.method, this.url, ms);
});

// 设置静态资源目录
app.use(require('koa-static')(__dirname + '/public'));

// 定义路由
koa.use('/', index.routes(), index.allowedMethods());
koa.use('/users', users.routes(), users.allowedMethods());
koa.use('/test', test.routes(), test.allowedMethods());

// 使路由生效
app.use(koa.routes());

// 监听错误
app.on('error', function(err, ctx){
	log.error('server error', err, ctx);
});

module.exports = app;

如此,所有127.0.0.1:3000/test开始的地址都将被路由到test.js中。