下一代 Web 框架 Koa

主要内容

  1. 了解 Koa 框架
  2. 学会 koa-genertor
  3. 了解 Node.js Web 框架的演进过程

1.1 Koa 简介

Koa 是 Node.js 的下一代 Web框架。

Koa 是由 Express 原班人马打造,是一个更小更健壮更富有表现力的 Web “微”框架。
进而实现使用 Koa 编写 Web 应用,通过组合各种更高级的异步流程控制中间件,来免除重复繁琐的回调函数嵌套,并极大提升常见错误的处理效率。

关于 Koa 的 V1 和 V2 差异

  1. 要明确的是 v1 和 v2 版本 API 方面基本无差异
  2. Koa v1 是基于 ES6 Generator 的。
  3. Koa v2 正式版本发布前,可通过 koa-convert 支持 3 种中间件写法,更现代,更时尚。
  4. Koa v2 正式版本发布后,主打 async 函数,要求使用 Node.js v7.6 以上版本。
  5. Koa v1 使用隐式的 this 作文上下文,而 Koa v2 则使用显式的 ctx 作为上下文,语义更清晰。

p.s Koa v2 版本在 2017 年 3 月发布

1.1.1 应用场景

以下列出了 Koa 的常用场景。

场景 描述 使用人员
传统 Web 应用开发 Koa 可以开发带有视图渲染和数据库操作的 Web 应用,主要以网站为主,前后端混在一起,开发简单,是入门和快速开发的利器 均可
作为服务端接口 使用 Koa 可以为 pc端,移动端,html5 端等提供 http API 支持 后端开发人员居多
作为独立 API 层 后端程序可能有多种语言实现,业务划分会导致跨域等各种情况出现,此时可以使用 Koa 作为 API 代理,来请求后端 API,处理后再将结果返回给前端 前端开发人员居多
RPC服务组装 由于历史问题,很多应用层采用 RPC 进行服务化,然后组装成 RPC 服务将其包装成最终 HTTP API提供调用。这是非常好的方式,这种场景是 Koa 非常擅长的组装 RPC 服务非常简单,不涉及数据库操作,可以按照前端要求的格式处理 均可
静态 API 模拟 Koa 可以提供静态 API 接口,无须实现具体逻辑,能够加速开发 均可
API 网关 使用 Node.js 实现 HTTP 代理是非常简单的,使用 Koa 能够更好地请求转发 均可
与前端框架集成 Koa为 Vue,React 等前端框架的集成提供开发部署环境的 HTTP 服务,静态 API 服务等,结合使用可以实现服务端渲染或同构开发。 前端开发人员居多
开发 Web 框架 Koa 自身没用绑定任何中间件,使用 Koa 是往往要同时使用多个中间件,所以很多框架更愿意将 Koa 作为内核模块,在其之上进行定制开发。比如,知名框架 ThinkJS 在其 v 3.0 中采用 Koa 作为内核模块,抛弃了之前维护的 HTTP 基础库 均可

1.1.2 开发要点

Koa 自身比较简单,但是要想使用好,需要掌握以下开发要点。

  • Koa 中间件
  • ES6 语法:Koa 是基于 Node.js v4 以上版本进行开发的,所以对 ES6 语法支持的非常好。
  • HTTP 基础
  • 异步流控制:推荐顺序是, async函数 -> Promise -> Generator。
  • 数据库操作:几乎所有的 Web 应用都涉及操作数据库,所以掌握数据库知识非常重要。数据库一般分为关系型数据库和飞关系型数据库。
  • API 接口开发

1.1.3 Koa 入门

Koa v2 的核心是使用面向更新特性的 async 函数的中间件,其正式版本发布前后略有不同。

  • 正式版本发布前:支持 3 种中间件的写法(Promise,Generator,async函数)。
  • 正式版本发布后:推荐使用 ES2017 的 async 函数作为中间件。
下面将会是以代码为主导的示例。
  1. 初始化项目
    这是使用 npm 初始化
// 初始化 Node.js 模块,创建 package.json 配置文件
npm init -y
// 安装 Koa 作为依赖模块
npm  i -S koa@2
// 创建 app.js 作为应用入口
touch app.js  // ( win 版本略有不同,可手动创建 )

接下来在 app.js 中写入以下服务代码:

const Koa = require('koa')
const app = new Koa()

// 日志中间件
app.use( async (ctx, next) => {
  const start = new Date()
  
  console.log('before await..')
  await next()
  console.log('after await...')

  const ms = new Date - start
  console.log(`${ctx.method} ${ctx.url} - ${ms} ms`)
} )

// 响应
app.use( async (ctx, next) => {
  console.log('respones...')
  ctx.body = 'Hello Koa 2'  
} )

app.listen(3000)

下面是对 Koa 代码中的要点进行说明。

  • 中间件使用了 async函数 + 箭头函数,这样的语义比 之前的 ES6 Generator 更加清晰。
  • 参数增加了 ctx,比之前的 ES6 Generator 中间件只能使用隐式的 this 作为上下文更加友好。

在执行 app.js 之前,一定要确保你的 Node.js 是 v7.6 以上的,否则无法直接执行带有 async 函数的代码。

node app.js

tip: 为什么 Koa 中要新增一个 ctx 参数
新增 ctx 参数的最主要的原因是在箭头函数中,this 实在定义时绑定的,而不是在运行时绑定的。

Koa v1 和 Koa v2 的用法差异
Koa v1

const koa = require('koa')
const app = koa();

Koa v2

const Koa = require('koa')
const app = new Koa();

v1 和 v2 的差异主要来源于源码结构的变化

  • v1 部分源码
var app = App.prototype;

module.exports = App;

function App() {
  if (! (this instanceof App) ) {
    return new App;
  }
  this.env = process.env.NODE_ENV || 'development';
  this.subdomainOffset = 2;
  this.middleware = [];
  this.proxy = false;
  this.context = Object.create(context);
  this.request = Object.create(request);
  this.create = Object.create(response);
}
  • v2 部分源码
module.exports = class App extends Emitter {
  constructor() {
    super();
    
    this.subdomainOffset = 2;
    this.middleware = [];
    this.proxy = false;
    this.context = Object.create(context);
    this.request = Object.create(request);
    this.create = Object.create(response);
  }
}

通过上面的源码对比,可以看出 v1 对外导出的函数,而 v2 对外导出的类,需要通过 new 这个关键子来实例化。另外,值得注意的是, v2 源码里,只有 App 进行了类化,其他仍然保持之前的风格。

1.1.4 为什么选择 Koa

为什么要在众多的框架中选择 Koa 呢,理由大概如下。

  • 用 async 函数做异步流程控制时,代码更容易理解。
  • 错误处理的干干净净。无论是 async 函数还是 Promise 规范都能很好地处理异常,另外 Koa 继承自 Event 的,结合 ctx 里的一些 API 能够更简单地处理错误。
  • 具有优雅的回形针中间件机制。通过更少的代码可以完成更多的工作,尤其是能对响应部分做拦截。(可以跟 Express 作对比)
  • 性能非常好。(跟 Express 作对比)
  • Koa 核心代码量比较少,易于定制,易于在其上开发各种 Web框架。
  • 社区生态逐渐完善。
  • 国内外很多公司都已经大量应用 Koa 了,目前 Node.js 的首选 Web 架构是 Koa。
  • 拥有 Egg.js (基于 Koa 的成熟的企业级 Web 开发框架),拥有庞大的插件生态。
  • 拥有 MidwayJS。它基于 Egg.js 生态,使用 TS 编写,提供 IoC 容器,是面向未来的框架。

下面的部分讲继续介绍 Koa-generator 和 Node.js Web 框架的演进之路

你可能感兴趣的:(下一代 Web 框架 Koa)