简介

熟悉Spring MVC的朋友应该都清楚Spring MVC是基于servlet的代码框架,这是最传统的web框架。然后在Spring5中引入了Spring WebFlux,这是基于reactive-netty的异步IO框架。

同样的,nodejs在最初的Express 3基础上发展起来了异步的koa框架。koa使用了promises和aysnc来避免JS中的回调地狱,并且简化了错误处理。

今天我们要来介绍一下这个优秀的nodejs框架koa。

koa和express

koa不再使用nodejs的req和res,而是封装了自己的ctx.request和ctx.response。

express可以看做是nodejs的一个应用框架,而koa则可以看成是nodejs 的http模块的抽象。

和express提供了Middleware,Routing,Templating,Sending Files和JSONP等特性不同的是,koa的功能很单一,如果你想使用其他的一些功能比如routing,sending files等功能,可以使用koa的第三方中间件。

koa并不是来替换express的,就像spring webFlux并不是用来替换spring MVC的。koa只是用Promises改写了控制流,并且避免了回调地狱,并提供了更好的异常处理机制。

koa使用介绍

koa需要node v7.6.0+版本来支持ES2015和async function。

我们看一个最最简单的koa应用:

const Koa = require('koa');
const app = module.exports = new Koa(); app.use(async function(ctx) {
ctx.body = 'Hello World';
}); if (!module.parent) app.listen(3000);

koa应用程序就是一个包含了很多个中间件的对象,这些中间件将会按照类似stack的执行顺序一个相应request。

中间件的级联关系

koa.use中传入的是一个function,我们也可以称之为中间件。

koa可以use很多个中间件,举个例子:

const Koa = require('koa');
const app = new Koa(); app.use(async (ctx, next) => {
await next();
console.log('log3');
}); app.use(async (ctx, next) => {
await next();
console.log('log2');
}); app.use(async ctx => {
console.log('log3');
}); app.listen(3000);

上面的例子中,我们调用了多次next,只要我们调用next,调用链就会传递到下一个中间件进行处理,一直到某个中间件不再调用next

为止。

上面的代码运行输出:

log1
log2
log3

koa的构造函数

我们看下koa的构造函数:

constructor(options) {
super();
options = options || {};
this.proxy = options.proxy || false;
this.subdomainOffset = options.subdomainOffset || 2;
this.proxyIpHeader = options.proxyIpHeader || 'X-Forwarded-For';
this.maxIpsCount = options.maxIpsCount || 0;
this.env = options.env || process.env.NODE_ENV || 'development';
if (options.keys) this.keys = options.keys;
this.middleware = [];
this.context = Object.create(context);
this.request = Object.create(request);
this.response = Object.create(response);
// util.inspect.custom support for node 6+
/* istanbul ignore else */
if (util.inspect.custom) {
this[util.inspect.custom] = this.inspect;
}
}

可以看到koa接收下面几个参数:

  • app.env 默认值是NODE_ENV或者development
  • app.keys 为cookie签名的keys

看下怎么使用:

app.keys = ['secret1', 'secret2'];
app.keys = new KeyGrip(['secret1', 'secret2'], 'sha256'); ctx.cookies.set('name', 'jack', { signed: true });
  • app.proxy 是否支持代理
  • app.subdomainOffset 表示子域名是从第几级开始的,这个参数决定了request.subdomains的返回结果,默认值为2
  • app.proxyIpHeader proxy ip header默认值是X-Forwarded-For
  • app.maxIpsCount 从proxy ip header读取的最大ip个数,默认值是0表示无限制。

我们可以这样用:

const Koa = require('koa');
const app = new Koa({ proxy: true });

或者这样用:

const Koa = require('koa');
const app = new Koa();
app.proxy = true;

启动http server

koa是一种web框架,web框架就需要开启http服务,要启动http服务,需要调用nodejs中的Server#listen()方法。

在koa中,我们可以很方便的使用koa#listen方法来启动这个http server:

const Koa = require('koa');
const app = new Koa();
app.listen(3000);

上面的代码相当于:

const http = require('http');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);

当然你可以同时创建http和https的服务:

const http = require('http');
const https = require('https');
const Koa = require('koa');
const app = new Koa();
http.createServer(app.callback()).listen(3000);
https.createServer(app.callback()).listen(3001);

自定义中间件

koa中的中间件是参数值为(ctx, next)的function。在这些方法中,需要手动调用next()以传递到下一个middleware。

下面看一下自定义的中间件:

async function responseTime(ctx, next) {
const start = Date.now();
await next();
const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`);
} app.use(responseTime);
  • 给中间件起个名字:

虽然中间件function只接收参数(ctx, next),但是我可以将其用一个wrapper方法包装起来,在wrapper方法中,我们给中间件起个名字 :

function logger(name) {
return async function logger(ctx, next) {
console.log(name);
await next();
};
}
  • 自定义中间件的扩展:

上面的wrapper创建方式还有另外一个好处,就是可以在自定义中间件中访问传入的参数,从而可以根据传入的参数,对自定义中间件进行扩展。

function logger(format) {
format = format || ':method ":url"'; return async function (ctx, next) {
const str = format
.replace(':method', ctx.method)
.replace(':url', ctx.url); console.log(str); await next();
};
} app.use(logger());
app.use(logger(':method :url'));
  • 组合多个中间件:

当有多个中间件的情况下,我们可以使用compose将其合并:

const compose = require('koa-compose');
const Koa = require('koa');
const app = module.exports = new Koa(); // x-response-time async function responseTime(ctx, next) {
const start = new Date();
await next();
const ms = new Date() - start;
ctx.set('X-Response-Time', ms + 'ms');
} // logger async function logger(ctx, next) {
const start = new Date();
await next();
const ms = new Date() - start;
if ('test' != process.env.NODE_ENV) {
console.log('%s %s - %s', ctx.method, ctx.url, ms);
}
} // response async function respond(ctx, next) {
await next();
if ('/' != ctx.url) return;
ctx.body = 'Hello World';
} // composed middleware const all = compose([
responseTime,
logger,
respond
]); app.use(all); if (!module.parent) app.listen(3000);

异常处理

在koa中怎么进行异常处理呢?

通用的方法就是try catch:


app.use(async (ctx, next) => {
try {
await next();
} catch (err) {
err.status = err.statusCode || err.status || 500;
throw err;
}
});

当然你也可以自定义默认的error处理器:

app.on('error', err => {
log.error('server error', err)
});

我们还可以传入上下文信息:

app.on('error', (err, ctx) => {
log.error('server error', err, ctx)
});

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/koa-startup/

本文来源:flydean的博客

欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

第四代Express框架koa简介的更多相关文章

  1. 【转载】Express、Koa、Hapi框架对比

    中文翻译:http://ourjs.com/detail/5490db1c8a34fa320400000e 英文原文:https://www.airpair.com/node.js/posts/nod ...

  2. Node.js 框架对比之 Express VS Koa

    背景 上图是一个典型的采用 Node.js 开发 web 应用的前后端结构,下面介绍一下 Node 服务层在其中的作用以及使用 Node.js 的一些优劣. Node 服务层作用: 请求代理 传统做法 ...

  3. Node.js实现RESTful api,express or koa?

    文章导读: 一.what's RESTful API 二.Express RESTful API 三.KOA RESTful API 四.express还是koa? 五.参考资料 一.what's R ...

  4. Node.js Express 框架

    Node.js Express 框架 Express 简介 Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP ...

  5. node.js之express框架入门篇

    一.express框架简介 express框架是后台的Node框架,在后台的受欢迎的程度,和jQuery一样 英语官网:http://expressjs.com/ 中文官网:http://www.ex ...

  6. node框架koa

    node的两大常见web服务器框架有express和koa,之前已经介绍过express了现在来介绍下koa吧~ koa也是express团队的出品,意在利用es7新出的async来告别"回 ...

  7. [转]分别使用Node.js Express 和 Koa 做简单的登录页

    本文转自:https://blog.csdn.net/weixin_38498554/article/details/79204240 刚刚学了Koa2,由于学的不是很深,并没有感受到网上所说的Koa ...

  8. node.js之express框架

    之前学习过node.js接触过express框架,最近为了编写一个mock server正好用到了express.下面正好就跟大家介绍一下关于express.今天的内容主要围绕这么几个方面? expr ...

  9. 用nodejs的express框架在本机快速搭建一台服务器

    [本文出自天外归云的博客园] 简介 用express框架在本机搭建一个服务器,这样大家可以通过指定的url来在你的服务器上运行相应的功能. Express是一个基于nodejs的框架,我们可以用它来完 ...

随机推荐

  1. DOM4J API

    1.DOM4J简介 DOM4J是 dom4j.org 出品的一个开源 XML 解析包.DOM4J应用于 Java 平台,采用了 Java 集合框架并完全支持 DOM,SAX 和 JAXP. DOM4J ...

  2. 一个Task.Factory.StartNew的错误用法

    同事写了这样一段代码: FactoryStartNew类: using System; using System.Collections.Generic; using System.Linq; usi ...

  3. python进程间共享数值、字典、列表变量

    ##python进程间共享数值.字典.列表变量 关注公众号"轻松学编程"了解更多. import multiprocessing def worker(num, mgr_dict, ...

  4. python类的封装与继承

    封装 关注公众号"轻松学编程"了解更多. 1.概念 面向对象语言的三大特征:封装, 继承, 多态. 广义的封装: 类和函数的定义本身就是封装的体现. 狭义的封装:一个类的某些属性, ...

  5. Flink的DataSource三部曲之一:直接API

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  6. Windows Server 2012 R2 辅助域控制器搭建

    Windows Server 2012 R2 辅助域控制器搭建 以下操作都是基于主域已搭建成功的基础上,全程操作过程都是在辅域上操作完成. 地址 主域:10.228.81.207 辅域:10.228. ...

  7. PS零基础入门教程--裁剪工具用法

    我是IT轩,分享一下我使用PS的一些用法,希望对大家有帮助!欢迎关注微信公众号:笑林新记 PS版本:PS CC 2019 主要技术:裁剪工具. 裁剪工具主要有:裁剪工具.透视裁剪工具.切片工具和切片选 ...

  8. 为研发同学定制的MySQL面试指南 - “能谈谈基数统计吗?”

    ** 目录 推荐阅读原文链接 一.基数是啥? 二.InnoDB更新基数的时机? 三.基数是估算出来 四.持久化基数 四.如何主动更新基数? 欢迎关注 Hi,大家好!我是白日梦. 今天我要跟你分享的话题 ...

  9. python爬虫00什么是爬虫

    用一个自动化的程序把网站背后的程序爬取下来. 在互联网上许许多多的网站,他们都是托管在服务器上的,这些服务器24小时运行着,刻刻 等待着别人的请求.所以,爬虫首先会模拟请求,就好像你在浏览器输入网址, ...

  10. 6 MyISAM和InnoDB

    6 MyISAM和InnoDB MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好.甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直 ...