Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs(middleware): use async #1703

Merged
merged 2 commits into from
Nov 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 31 additions & 31 deletions docs/source/en/basics/middleware.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
title: Middleware
---

In [the previous chapter](../intro/egg-and-koa.md), we say that Egg is based on Koa 1, so the form of middleware in Egg is the same as in Koa 1, i.e. they are both based on [the onion model](../intro/egg-and-koa.md#midlleware) of generator function.
In [the previous chapter](../intro/egg-and-koa.md), we say that Egg is based on Koa, so the form of middleware in Egg is the same as in Koa, i.e. they are both based on [the onion model](../intro/egg-and-koa.md#midlleware).

## Writing Middleware

### How to write

We begin to see how to write a middleware from a simple gzip example.
Let's take a look at how to write a middleware from a simple gzip example.

```js
const isJSON = require('koa-is-json');
const zlib = require('zlib');

function* gzip(next) {
yield next;
async function gzip(ctx, next) {
await next();

// convert the response body to gzip after the completion of the execution of subsequent middleware
let body = this.body;
let body = ctx.body;
if (!body) return;
if (isJSON(body)) body = JSON.stringify(body);

// set gzip body, correct the response header
const stream = zlib.createGzip();
stream.end(body);
this.body = stream;
this.set('Content-Encoding', 'gzip');
ctx.body = stream;
ctx.set('Content-Encoding', 'gzip');
}
```

You might find that the middleware's writing style in the framework is exactly the same as in Koa, so any middleware in Koa can be used directly by the framework.
You might find that the middleware's style in the framework is exactly the same as in Koa, yes, any middleware in Koa can be used directly by the framework.

### Configuration

Expand All @@ -41,32 +41,37 @@ Usually the middleware has its own configuration. In the framework, a complete m
We will do a simple optimization to the gzip middleware above, making it do gzip compression only if the body size is greater than a configured threshold. So, we need to create a new file `gzip.js` in `app/middleware` directory.

```js
// app/middleware/gzip.js
const isJSON = require('koa-is-json');
const zlib = require('zlib');

module.exports = options => {
return function* gzip(next) {
yield next;
return async function gzip(ctx, next) {
await next();

// convert the response body to gzip after the completion of the execution of subsequent middleware
let body = this.body;
let body = ctx.body;
if (!body) return;

// support options.threshold
if (options.threshold && this.length < options.threshold) return;
if (options.threshold && ctx.length < options.threshold) return;

if (isJSON(body)) body = JSON.stringify(body);

// set gzip body, correct the response header
const stream = zlib.createGzip();
stream.end(body);
this.body = stream;
this.set('Content-Encoding', 'gzip');
ctx.body = stream;
ctx.set('Content-Encoding', 'gzip');
};
};
```

## Using Middleware in Application
## Using Middleware

After writing middleware, we also need to mount it.

### Using Middleware in Application

We can load customized middleware completely by configuration in the application, and decide their order.
If we need to load the gzip middleware in the above,
Expand All @@ -93,16 +98,15 @@ Framework and Plugin don't support `config.middleware`, you should mount it in `
```js
// app.js
module.exports = app => {
// 在中间件最前面统计请求时间
// put to the first place to count request cost
app.config.coreMiddleware.unshift('report');
};

// app/middleware/report.js
module.exports = () => {
return function* (next) {
return async function (ctx, next) {
const startTime = Date.now();
yield next;
// 上报请求时间
await next();
reportTime(Date.now() - startTime);
}
};
Expand All @@ -119,7 +123,7 @@ If you do want to take effect on the corresponding routes, you could just mount
```js
module.exports = app => {
const gzip = app.middlewares.gzip({ threshold: 1024 });
app.get('/needgzip', gzip, app.controller.handler);
app.router.get('/needgzip', gzip, app.controller.handler);
};
```

Expand All @@ -140,12 +144,7 @@ module.exports = {

## Use Koa's Middleware

The framework is compatible with all kinds of middleware of Koa 1.x and 2.x, including:
- generator function: `function* (next) {}`
- async function: `async (ctx, next) => {}`
- common function: `(ctx, next) => {}`

All middleware used by Koa can be directly used by the framework, too.
Developer is free to use Koa Middleware, all middleware used by Koa can be directly used by the framework too.

For example, Koa uses [koa-compress](https://github.com/koajs/compress) in this way:

Expand All @@ -163,19 +162,20 @@ We can load the middleware according to the framework specification like this:

```js
// app/middleware/compress.js

// interfaces(`(options) => middleware`) exposed by koa-compress match the framework middleware requirements
module.exports = require('koa-compress');
```

```js
// config/config.default.js

exports.middleware = [ 'compress' ];
exports.compress = {
threshold: 2048,
module.exports = {
middleware: [ 'compress' ],
compress: {
threshold: 2048,
},
};
```

## General Configuration

These general config fields are supported by middleware loaded by the application layer or built in by the framework:
Expand Down
60 changes: 30 additions & 30 deletions docs/source/zh-cn/basics/middleware.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
title: Middleware 中间件
---

在[前面的章节](../intro/egg-and-koa.md)中,我们介绍了 Egg 是基于 Koa 1 实现的,所以 Egg 的中间件形式和 Koa 1 的中间件形式是一样的,都是基于 generator function 的[洋葱圈模型](../intro/egg-and-koa.md#midlleware)。每次我们编写一个中间件,就相当于在洋葱外面包了一层。
在[前面的章节](../intro/egg-and-koa.md)中,我们介绍了 Egg 是基于 Koa 实现的,所以 Egg 的中间件形式和 Koa 的中间件形式是一样的,都是基于[洋葱圈模型](../intro/egg-and-koa.md#midlleware)。每次我们编写一个中间件,就相当于在洋葱外面包了一层。

## 编写中间件

Expand All @@ -10,22 +10,23 @@ title: Middleware 中间件
我们先来通过编写一个简单的 gzip 中间件,来看看中间件的写法。

```js
// app/middleware/gzip.js
const isJSON = require('koa-is-json');
const zlib = require('zlib');

function* gzip(next) {
yield next;
async function gzip(ctx, next) {
await next();

// 后续中间件执行完成后将响应体转换成 gzip
let body = this.body;
let body = ctx.body;
if (!body) return;
if (isJSON(body)) body = JSON.stringify(body);

// 设置 gzip body,修正响应头
const stream = zlib.createGzip();
stream.end(body);
this.body = stream;
this.set('Content-Encoding', 'gzip');
ctx.body = stream;
ctx.set('Content-Encoding', 'gzip');
}
```

Expand All @@ -41,32 +42,37 @@ function* gzip(next) {
我们将上面的 gzip 中间件做一个简单的优化,让它支持指定只有当 body 大于配置的 threshold 时才进行 gzip 压缩,我们要在 `app/middleware` 目录下新建一个文件 `gzip.js`

```js
// app/middleware/gzip.js
const isJSON = require('koa-is-json');
const zlib = require('zlib');

module.exports = options => {
return function* gzip(next) {
yield next;
return async function gzip(ctx, next) {
await next();

// 后续中间件执行完成后将响应体转换成 gzip
let body = this.body;
let body = ctx.body;
if (!body) return;

// 支持 options.threshold
if (options.threshold && this.length < options.threshold) return;
if (options.threshold && ctx.length < options.threshold) return;

if (isJSON(body)) body = JSON.stringify(body);

// 设置 gzip body,修正响应头
const stream = zlib.createGzip();
stream.end(body);
this.body = stream;
this.set('Content-Encoding', 'gzip');
ctx.body = stream;
ctx.set('Content-Encoding', 'gzip');
};
};
```

## 在应用中使用中间件
## 使用中间件

中间件编写完成后,我们还需要手动挂载,支持以下方式:

### 在应用中使用中间件

在应用中,我们可以完全通过配置来加载自定义的中间件,并决定它们的顺序。

Expand All @@ -86,7 +92,7 @@ module.exports = {

该配置最终将在启动时合并到 `app.config.appMiddleware`。

## 在框架和插件中使用中间件
### 在框架和插件中使用中间件

框架和插件不支持在 `config.default.js` 中匹配 `middleware`,需要通过以下方式:

Expand All @@ -99,9 +105,9 @@ module.exports = app => {

// app/middleware/report.js
module.exports = () => {
return function* (next) {
return async function (ctx, next) {
const startTime = Date.now();
yield next;
await next();
// 上报请求时间
reportTime(Date.now() - startTime);
}
Expand All @@ -110,15 +116,15 @@ module.exports = () => {

应用层定义的中间件(`app.config.appMiddleware`)和框架默认中间件(`app.config.coreMiddleware`)都会被加载器加载,并挂载到 `app.middleware` 上。

## router 中使用中间件
### router 中使用中间件

以上两种方式配置的中间件是全局的,会处理每一次请求。
如果你只想针对单个路由生效,可以直接在 `app/router.js` 中实例化和挂载,如下:

```js
module.exports = app => {
const gzip = app.middlewares.gzip({ threshold: 1024 });
app.get('/needgzip', gzip, app.controller.handler);
app.router.get('/needgzip', gzip, app.controller.handler);
};
```

Expand All @@ -138,13 +144,7 @@ module.exports = {

## 使用 Koa 的中间件

框架兼容 Koa 1.x 和 2.x 支持的所有形式的中间件,包括:

- generator function: `function* (next) {}`
- async function: `async (ctx, next) => {}`
- common function: `(ctx, next) => {}`

所有可以在 Koa 中使用的中间件都可以直接在框架中使用。
在框架里面可以非常容易的引入 Koa 中间件生态。

以 [koa-compress](https://github.com/koajs/compress) 为例,在 Koa 中使用时:

Expand All @@ -162,17 +162,17 @@ app.use(compress(options));

```js
// app/middleware/compress.js

// koa-compress 暴露的接口(`(options) => middleware`)和框架对中间件要求一致
module.exports = require('koa-compress');
```

```js
// config/config.default.js

exports.middleware = [ 'compress' ];
exports.compress = {
threshold: 2048,
module.exports = {
middleware: [ 'compress' ],
compress: {
threshold: 2048,
},
};
```

Expand Down