diff --git a/docs/_config.yml b/docs/_config.yml index 748d1769a4..37036bca26 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,4 +1,4 @@ -title: egg +title: Egg.js subtitle: "Born to build better enterprise frameworks and apps" description: "Born to build better enterprise frameworks and apps" language: diff --git a/docs/source/_data/guide_toc.yml b/docs/source/_data/guide_toc.yml index 2ce3f3781d..23e4f3982c 100644 --- a/docs/source/_data/guide_toc.yml +++ b/docs/source/_data/guide_toc.yml @@ -1,5 +1,5 @@ Intro: - What is egg: /intro/index.html + What is Egg: /intro/index.html Egg and Koa: /intro/egg-and-koa.html Get Start: /intro/quickstart.html Basics: diff --git a/docs/source/en/basics/env.md b/docs/source/en/basics/env.md index 5fbe8545e5..dd58783099 100644 --- a/docs/source/en/basics/env.md +++ b/docs/source/en/basics/env.md @@ -3,7 +3,7 @@ title: Runtime Environment # Runtime Environment -There could be all kinds of difference during various stages of a web application development, but the application itself should be stateless, so EGG provide environment variables to cope with such difference. +There could be all kinds of difference during various stages of a Web application development, but the application itself should be stateless, so EGG provide environment variables to cope with such difference. EGG framework provides a variable named `env` for setting up the runtime environment. The `env` could be used to determine which configuration file should be applied, or you can perform any operations by detecting the `env` directly. @@ -27,7 +27,7 @@ You can also load different configuration file for different environment by addi ## Difference with NODE_ENV -Lots of node applications use `NODE_ENV` for environment setting, but `EGG_SERVER_ENV` distinguishes the environments much more specific. Generally speaking, there are local environment, unit test environment, test environment, production environment during the application development. Test and production environment are **Server Environment** and their `NODE_ENV` should be set to `production` , just like how npm make use of `NODE_ENV`. when you depoly applications in test and production environment, you don't install the devDependencies, so `production` should be applied. +Lots of Node.js applications use `NODE_ENV` for environment setting, but `EGG_SERVER_ENV` distinguishes the environments much more specific. Generally speaking, there are local environment, unit test environment, test environment, production environment during the application development. Test and production environment are **Server Environment** and their `NODE_ENV` should be set to `production` , just like how npm make use of `NODE_ENV`. when you depoly applications in test and production environment, you don't install the devDependencies, so `production` should be applied. Default mapping of `EGG_SERVER_ENV` and `NODE_ENV` (will generate `EGG_SERVER_ENV` from `NODE_ENV` setting if `EGG_SERVER_ENV` is not specified) @@ -47,4 +47,4 @@ Set `EGG_SERVER_ENV` to `sit` (also set `NODE_ENV = production` as recommend), t ## Difference with Koa -We are using `app.env` to distinguishes the environments in koa, and `app.env` defualt to `process.env.NODE_ENV`. But in egg (and frameworks base on egg), we put all the configurations in `app.config`, so we should use `app.config.env` to distinguishes the environments, `app.env` is no logger used. +We are using `app.env` to distinguishes the environments in Koa, and `app.env` defualt to `process.env.NODE_ENV`. But in Egg (and frameworks base on Egg), we put all the configurations in `app.config`, so we should use `app.config.env` to distinguishes the environments, `app.env` is no logger used. diff --git a/docs/source/en/faq.md b/docs/source/en/faq.md index 2ed71608b4..aa7fd86d56 100644 --- a/docs/source/en/faq.md +++ b/docs/source/en/faq.md @@ -1,7 +1,7 @@ title: FAQ --- -If you have questions that is not contained below, please check [egg issues](https://github.com/eggjs/egg/issues). +If you have questions that is not contained below, please check [Egg issues](https://github.com/eggjs/egg/issues). ## Why my config don't work ? @@ -47,6 +47,6 @@ There are two kinds of common csrf errors: - `missing csrf token` - `invalid csrf token` -By default [egg-security](https://github.com/eggjs/egg-security/) plugin built in egg requires CSRF validation against all 'unsafe' request such as `POST`, `PUT`, `DELETE` requests. +By default [egg-security](https://github.com/eggjs/egg-security/) plugin built in Egg requires CSRF validation against all 'unsafe' request such as `POST`, `PUT`, `DELETE` requests. The error will disappear in the presence of correct csrf token in request. For more implentation details, see [./core/security.md#csrf]. diff --git a/docs/source/en/intro/egg-and-koa.md b/docs/source/en/intro/egg-and-koa.md index a462a0a0c0..bb7c82e364 100644 --- a/docs/source/en/intro/egg-and-koa.md +++ b/docs/source/en/intro/egg-and-koa.md @@ -1,4 +1,4 @@ -title: egg and koa +title: Egg and Koa --- ## Asynchronous programming model @@ -6,13 +6,13 @@ title: egg and koa Node.js is an asynchronous world, asynchronous programming models in official API support are all in callback form ,it brings many problems. For example: - [callback hell](http://callbackhell.com/): Notorious "callback hell"。 -- [release zalgo](https://oren.github.io/blog/zalgo.html): Asynchronous functions may call callback function response data synchronously which would bring inconsistency. +- [release zalgo](https://oren.github.io/blog/zalgo.html): Asynchronous functions may call callback function response data synchronously which would bring inconsistency. The community has provided many solutions for the problems, the winner is Promise, it is built into ECMAScript 2015. On the basis of Promise, and Generator with the ability to switch context, we can write asynchronous code in synchronous way with [co] and other third party libraries. Meanwhile [async function], the official solution has been finalized, and will be published in ECMAScript 2017. ### Generator and co -#### Asynchronous programming model in synchronous way on basis of Generator and Promise. +#### Asynchronous programming model in synchronous way on basis of Generator and Promise. As metioned before, we can write asynchronous code in synchronous way with the help of Generator and Promise. The most popular library implementing this feature is [co]. the core principle of [co] can be described by lines of code below: @@ -50,7 +50,7 @@ run(main()); With the run function, asynchronous code can be written in synchronous way in main function in the example above. If you want to know more about Generator, you can have a look at [this document](https://github.com/dead-horse/koa-step-by-step#generator) -Compared with the run function, [co] has `yield [Object / Array / thunk / Generator Function / Generator]`, and builds a Promise with wrapping a Generator Function. [co] is also the underlying library of koa 1 providing the asynchronous feature. Every middleware in koa 1 must be a `generator function`. +Compared with the run function, [co] has `yield [Object / Array / thunk / Generator Function / Generator]`, and builds a Promise with wrapping a Generator Function. [co] is also the underlying library of Koa 1 providing the asynchronous feature. Every middleware in Koa 1 must be a `generator function`. ### Async function @@ -76,17 +76,17 @@ fn().then(res => console.log(res)).catch(err => console.error(err.stack)); Other than the features supported by [co], async function can not await a `Promise` array (You can wrap it with `Promise.all`), await `thunk` is not avaliable either. -Though async function has not been published with the spec yet, it is supported in the V8 runtime built in node 7.x, you can use it without flag parameter after 7.6.0 version. +Though async function has not been published with the spec yet, it is supported in the V8 runtime built in Node.js 7.x, you can use it without flag parameter after 7.6.0 version. ## Koa -> Koa is a new web framework designed by the team behind Express, which aims to be a smaller, more expressive, and more robust foundation for web applications and APIs. +> Koa is a new Web framework designed by the team behind Express, which aims to be a smaller, more expressive, and more robust foundation for Web applications and APIs. -The design style of koa and express are very similar, The underlying base library is the same, [HTTP library](https://github.com/jshttp). There are several significant differences between them. Besides the asynchronous solution by default metioned above, there are the following points. +The design style of Koa and Express are very similar, The underlying base library is the same, [HTTP library](https://github.com/jshttp). There are several significant differences between them. Besides the asynchronous solution by default metioned above, there are the following points. ### Midlleware -The middleware in koa is different from express, koa use the onion model: +The middleware in Koa is different from Express, Koa use the onion model: - Middleware onion diagram: @@ -96,16 +96,16 @@ The middleware in koa is different from express, koa use the onion model: ![](https://raw.githubusercontent.com/koajs/koa/a7b6ed0529a58112bac4171e4729b8760a34ab8b/docs/middleware.gif) -All the requests will be executed twice during one middleware. Compared to express middleware, it is very easy to implementing post-processing logic. You can obviously feel the advantage of koa middleware model comparing to the compress middleware implementing in koa and express. +All the requests will be executed twice during one middleware. Compared to Express middleware, it is very easy to implementing post-processing logic. You can obviously feel the advantage of Koa middleware model comparing to the compress middleware implementing in Koa and Express. -- [koa-compress](https://github.com/koajs/compress/blob/master/index.js) for koa. -- [compression](https://github.com/expressjs/compression/blob/master/index.js) for express. +- [koa-compress](https://github.com/koajs/compress/blob/master/index.js) for Koa. +- [compression](https://github.com/expressjs/compression/blob/master/index.js) for Express. ### Context -Unlike that there are only two objects `Request` and `Response` in express, koa has one more, `Context` object in one http request(it is `this` in koa 1, while it is the first parameter for middleware function in koa 2). We can attach all the relative things to the object. Such as [traceId](https://github.com/eggjs/egg-tracer/blob/1.0.0/lib/tracer.js#L12) that runs through the request lifetime (which will be called anywhere afterward) could be attached. It is more semantic other than request and response. +Unlike that there are only two objects `Request` and `Response` in Express, Koa has one more, `Context` object in one HTTP request(it is `this` in Koa 1, while it is the first parameter for middleware function in Koa 2). We can attach all the relative things to the object. Such as [traceId](https://github.com/eggjs/egg-tracer/blob/1.0.0/lib/tracer.js#L12) that runs through the request lifetime (which will be called anywhere afterward) could be attached. It is more semantic other than request and response. -At the same time Request and Response are attached to Context object. Just like express, the two objects provide lots of easy ways to help developing. For example: +At the same time Request and Response are attached to Context object. Just like Express, the two objects provide lots of easy ways to help developing. For example: - `get request.query` - `get request.hostname` @@ -130,16 +130,16 @@ function* onerror(next) { Putting the middleware before others, you can catch all the exceptions thrown by the synchronous or asynchronous code. -## Egg inherit from koa +## Egg inherit from Koa -As the above words, koa is an excellent framework. However, it is not enough to building an enterprise-class application. +As the above words, Koa is an excellent framework. However, it is not enough to building an enterprise-class application. -Egg is built around the koa. On the basis of koa model, egg implements enhancements one step further. +Egg is built around the Koa. On the basis of Koa model, Egg implements enhancements one step further. ### Extension -In the framework or application based on egg, we can extend the prototype of 4 koa objects by defining `app/extend/{application,context,request,response}.js`. With this, we can write more utility methods quickly. For example, we have the following code in `app/extend/context.js`: +In the framework or application based on Egg, we can extend the prototype of 4 Koa objects by defining `app/extend/{application,context,request,response}.js`. With this, we can write more utility methods quickly. For example, we have the following code in `app/extend/context.js`: ```js // app/extend/context.js @@ -166,13 +166,13 @@ More about extension, please check [Exception](../basics/extend.md) section. ### Plugin -As is known to all, Many middlewares are imported to provide different kind of features in express and koa. Eg, [koa-session](https://github.com/koajs/session) provides the session support, [koa-bodyparser](https://github.com/koajs/bodyparser) help to parse request body. Egg has provided a powerful plugin mechanism to make it more easy to write stand alone features. +As is known to all, Many middlewares are imported to provide different kind of features in Express and Koa. Eg, [koa-session](https://github.com/koajs/session) provides the Session support, [koa-bodyparser](https://github.com/koajs/bodyparser) help to parse request body. Egg has provided a powerful plugin mechanism to make it more easy to write stand alone features. One plugin can include: - extend:extend the context of base object, provide utility and attributes. -- middleware:add one or more middlewares, provide pre or post processing logic for request. -- config:configure the default value in different environments. +- middleware:add one or more middlewares, provide pre or post processing logic for request. +- config:configure the default value in different environments. Stand alone module plugin can provide rich features with high maintenancability. You can almost forget the configuration as the plugin supports configuring the default value in different environments. @@ -182,22 +182,22 @@ More about plugin, please check [plugin](../advanced/plugin.md) section. ### Roadmap -#### egg 1.x +#### Egg 1.x -The node LTS version now does not support async function,so egg is based on koa 1.x. On the basis of this, egg has added full async function support. Egg is completely compatible with middlewares in koa 2.x, all application layer are implemented based on [async function](../tutorials/async-function.md). +The Node.js LTS version now does not support async function,so Egg is based on Koa 1.x. On the basis of this, Egg has added full async function support. Egg is completely compatible with middlewares in Koa 2.x, all application layer are implemented based on [async function](../tutorials/async-function.md). -- The underlying is based on koa 1.x, asynchronous solution is based on generator function wrapped by [co]. -- Official plugin and core of egg are written in generator function, keep supporting node LTS version, use [co] when necessary to be compatiable with async function. -- Application developers can choose either async function(node 7.6+) or generator function(node 6.0+), **we recommend generator function way for ensuring you application can be runned on node LTS version**. +- The underlying is based on Koa 1.x, asynchronous solution is based on generator function wrapped by [co]. +- Official plugin and core of Egg are written in generator function, keep supporting Node.js LTS version, use [co] when necessary to be compatiable with async function. +- Application developers can choose either async function (Node.js 7.6+) or generator function (Node.js 6.0+), **we recommend generator function way for ensuring you application can be runned on Node.js LTS version**. -#### egg next +#### Egg next -Egg will transfer core to koa 2.x until node LTS supports async function, compatibility with generator function will also be kept. +Egg will transfer core to Koa 2.x until Node.js LTS supports async function, compatibility with generator function will also be kept. -- The underlying will be based on koa 2.x, asynchronous solution will be based on async function. +- The underlying will be based on Koa 2.x, asynchronous solution will be based on async function. - Official plugin and core of egge will be written in async function. - Recommend user transfer business layer to async function. -- node 6.x will be no longer supported. +- Node.js 6.x will be no longer supported. [co]: https://github.com/tj/co [Async function]: https://github.com/tc39/ecmascript-asyncawait diff --git a/docs/source/en/intro/index.md b/docs/source/en/intro/index.md index 29dd569d48..e590cfe0ea 100644 --- a/docs/source/en/intro/index.md +++ b/docs/source/en/intro/index.md @@ -1,32 +1,32 @@ -title: What is egg? +title: What is Egg? --- -**egg is born for building enterprise application and framework**,we hope egg will give birth to more application framework to help developers and developing team reduce development and maintenance costs. +**Egg is born for building enterprise application and framework**,we hope Egg will give birth to more application framework to help developers and developing team reduce development and maintenance costs. ## Design principles -Since we know well that enterprise applications need to consider how to balance the differences between different teams, seeking common ground while reserving differences in the pursuit of clarifying specification and cooperation, we focus on providing core features for web development and a flexible and extensible plug-in mechanism instead of giant bazaar mode which is popular in common web frameworks(with integrated such as database, template engine, front-end framework and other functions). We will not make technical selection because default technical selection makes the scalability of the framework too poor to meet a variety of custom requirements. With the help of egg , it is very easy for architects and technical leaders to build their own framework which is suitable for their business scenarios based on existing technology stack . +Since we know well that enterprise applications need to consider how to balance the differences between different teams, seeking common ground while reserving differences in the pursuit of clarifying specification and cooperation, we focus on providing core features for Web development and a flexible and extensible plug-in mechanism instead of giant bazaar mode which is popular in common Web frameworks(with integrated such as database, template engine, front-end framework and other functions). We will not make technical selection because default technical selection makes the scalability of the framework too poor to meet a variety of custom requirements. With the help of Egg , it is very easy for architects and technical leaders to build their own framework which is suitable for their business scenarios based on existing technology stack . -The plug-in mechanism of egg is very extensible, **one purpose for one plugin**(Eg:[nunjucks] is encapsulated in to [egg-view-nunjucks](https://github.com/eggjs/egg-view-nunjucks), and MySQL is encapsulated in to [egg-mysql](https://github.com/eggjs/egg-mysql)). Aggregating the plugins and customizing the configurations according to their own business scenarios greatly reduces the development cost. +The plug-in mechanism of Egg is very extensible, **one purpose for one plugin**(Eg: [Nunjucks] is encapsulated in to [egg-view-nunjucks](https://github.com/eggjs/egg-view-nunjucks), and MySQL is encapsulated in to [egg-mysql](https://github.com/eggjs/egg-mysql)). Aggregating the plugins and customizing the configurations according to their own business scenarios greatly reduces the development cost. -Egg is a convention-over-configuration framework, follows the [Loader](../advanced/loader.md) to do the development, it helps to reduce the cost of learning. Developers no longer work as 'nails'. The cost of communication is very high for a team without convention. it is easy to get fault without convention. However convention is not equal to diffcult extension, instead, egg does well in extension part, you can build your own framework according to team convention. [Loader](../advanced/loader.md) can help load different default configuration in different environment, egg default convention can also be covered by your own. +Egg is a convention-over-configuration framework, follows the [Loader](../advanced/loader.md) to do the development, it helps to reduce the cost of learning. Developers no longer work as 'nails'. The cost of communication is very high for a team without convention. it is easy to get fault without convention. However convention is not equal to diffcult extension, instead, Egg does well in extension part, you can build your own framework according to team convention. [Loader](../advanced/loader.md) can help load different default configuration in different environment, Egg default convention can also be covered by your own. -## differences between community framework +## Differences between community framework -[express] is well used in node community, it is easy and extensible, fit personal project a lot. However, without default convention, standard mvc model has lots of strange impl which would leads to misunderstand. egg's teamwork cost is really low by following convention convention-over-configuration. +[Express] is well used in Node.js community, it is easy and extensible, fit personal project a lot. However, without default convention, standard mvc model has lots of strange impl which would leads to misunderstand. Egg's teamwork cost is really low by following convention convention-over-configuration. -[sails] is a framework that also follows convention-over-configuration,it does well in extensible work. Compared with egg, [sails] supports blueprint REST API, [WaterLine] , Frontend integration, websocks and so on, all of these are provided by sails. Egg does not provide these functions, it only has integration of different functional extension, eg, egg-blueprint, egg-waterline, if you use sails-egg to integrate these extensions, sails can be replaced. +[Sails] is a framework that also follows convention-over-configuration,it does well in extensible work. Compared with Egg, [Sails] supports blueprint REST API, [WaterLine] , Frontend integration, websocks and so on, all of these are provided by Sails. Egg does not provide these functions, it only has integration of different functional extension, eg, egg-blueprint, egg-waterline, if you use sails-egg to integrate these extensions, [Sails] can be replaced. ## features - depth [customizd framework](../advanced/framework.md) -- highly extensible [plug-in mechanism] (../advanced/plugin.md) +- highly extensible [plug-in mechanism](../advanced/plugin.md) - built-in [cluster](../advanced/cluster.md) - based on [koa] with high performance - stable core framework with high test coverage. - [progressive development](../tutorials/progressive.md) -[sails]: http://sailsjs.com -[express]: http://expressjs.com -[koa]: http://koajs.com -[nunjucks]: https://mozilla.github.io/nunjucks +[Sails]: http://sailsjs.com +[Express]: http://expressjs.com +[Koa]: http://koajs.com +[Nunjucks]: https://mozilla.github.io/nunjucks [WaterLine]: https://github.com/balderdashy/waterline diff --git a/docs/source/en/intro/quickstart.md b/docs/source/en/intro/quickstart.md index a05886968f..8a924a2ab4 100644 --- a/docs/source/en/intro/quickstart.md +++ b/docs/source/en/intro/quickstart.md @@ -9,7 +9,7 @@ By following along with this guide step by step, you can quickly get started wit ## Prerequisites - Operating System: Linux, OS X or Windows. -- Node.js Runtime: 6.x or newer; it is recommended that you use [LTS Releases][node]. +- Node.js Runtime: 6.x or newer; it is recommended that you use [LTS Releases][Node.js]. ## the Quick Way @@ -149,7 +149,7 @@ to allow the developers to use different plug-ins for their individual needs. For more information, cf. [View](../core/view.md). -In this example, we will use [nunjucks]. +In this example, we will use [Nunjucks]. First install the corresponding plug-in [egg-view-nunjucks]. @@ -231,7 +231,7 @@ module.exports = app => { Open a browser window and navigate to http://localhost:7001/news. You should be able to see the rendered page. -**Tip:In development, egg enables the [development][egg-development] plug-in by default, which reloads your worker process when changes are made to your back-end code.** +**Tip:In development, Egg enables the [development][egg-development] plug-in by default, which reloads your worker process when changes are made to your back-end code.** ### Create a Service @@ -251,7 +251,7 @@ module.exports = app => { // read config const { serverUrl, pageSize } = this.app.config.news; - // use build-in http client to GET hacker-news api + // use build-in HttpClient to GET hacker-news api const { data: idList } = yield this.ctx.curl(`${serverUrl}/topstories.json`, { data: { orderBy: '"$key"', @@ -273,7 +273,7 @@ module.exports = app => { }; ``` -> Egg has [http client](../core/httpclient.md) built in in order to help you make http requests. +> Egg has [HttpClient](../core/httpclient.md) built in in order to help you make HTTP requests. Then slightly modify our previous controller. @@ -406,7 +406,7 @@ module.exports = app => { ### Add Unit Testing -Unit Testing is very important, and egg also provide [egg-bin] to help you write tests painless. +Unit Testing is very important, and Egg also provide [egg-bin] to help you write tests painless. ```js // test/app/middleware/robot.test.js @@ -469,11 +469,11 @@ Where to go from here? Browse our documentation to better understand the framewo [nvm]: https://github.com/creationix/nvm [nvs]: https://github.com/jasongin/nvs -[node]: http://nodejs.org +[Node.js]: http://nodejs.org [npm]: https://www.npmjs.org [egg-init]: https://github.com/eggjs/egg-init [egg-static]: https://github.com/eggjs/egg-static [egg-development]: https://github.com/eggjs/egg-development [egg-view-nunjucks]: https://github.com/eggjs/egg-view-nunjucks [urllib]: https://www.npmjs.com/package/urllib -[nunjucks]: https://mozilla.github.io/nunjucks/ +[Nunjucks]: https://mozilla.github.io/nunjucks/ diff --git a/docs/source/zh-cn/advanced/cluster-client.md b/docs/source/zh-cn/advanced/cluster-client.md index 55b5b03f37..f0dc304b25 100644 --- a/docs/source/zh-cn/advanced/cluster-client.md +++ b/docs/source/zh-cn/advanced/cluster-client.md @@ -387,7 +387,7 @@ class APIClient extends Base { constructor(options) { super(options); - // options.cluster 用于给 egg 的插件传递 app.cluster 进来 + // options.cluster 用于给 Egg 的插件传递 app.cluster 进来 this._client = (options.cluster || cluster)(RegistryClient).create(options); this._client.ready(() => this.ready(true)); @@ -469,4 +469,4 @@ exports.apiClient = { - ClusterClient - 通过 cluster-client 模块进行简单 wrap 得到的 client 实例,负责自动抹平多进程模型的差异。 - APIClient - 内部调用 ClusterClient 做数据同步,无需关心多进程模型,用户最终使用的模块。API 都通过此处暴露,支持同步和异步。 -有兴趣的同学可以看一下 [增强多进程研发模式](https://github.com/eggjs/egg/issues/322) 讨论过程。 +有兴趣的同学可以看一下[增强多进程研发模式](https://github.com/eggjs/egg/issues/322) 讨论过程。 diff --git a/docs/source/zh-cn/advanced/framework.md b/docs/source/zh-cn/advanced/framework.md index 68454bf821..bb70e82676 100644 --- a/docs/source/zh-cn/advanced/framework.md +++ b/docs/source/zh-cn/advanced/framework.md @@ -12,9 +12,9 @@ title: 框架开发 - 统一的技术选型,比如数据库、模板、前端框架及各种中间件设施都需要选型,而框架封装后保证应用使用一套架构。 - 统一的默认配置,开源社区的配置可能不适用于公司,而又不希望应用去配置。 - 统一的部署方案,通过框架和平台的双向控制,应用只需要关注自己的代码,具体查看[部署章节](./deployment.md) -- 统一的代码风格,框架不仅仅解决代码重用问题,还可以对应用做一定约束,作为企业框架是很必要的。egg 在 koa 基础上做了很多约定,框架可以使用 [Loader](./loader.md) 自己定义代码规则。 +- 统一的代码风格,框架不仅仅解决代码重用问题,还可以对应用做一定约束,作为企业框架是很必要的。Egg 在 Koa 基础上做了很多约定,框架可以使用 [Loader](./loader.md) 自己定义代码规则。 -为此,egg 为团队架构师和技术负责人提供 `框架定制` 的能力,框架是一层抽象,可以基于 egg 去封装上层框架,并且 egg 支持多层继承。 +为此,Egg 为团队架构师和技术负责人提供 `框架定制` 的能力,框架是一层抽象,可以基于 Egg 去封装上层框架,并且 Egg 支持多层继承。 这样,整个团队就可以遵循统一的方案,并且在项目中可以根据业务场景自行使用插件做差异化,当后者验证为最佳实践后,就能下沉到框架中,其他项目仅需简单的升级下框架的版本即可享受到。 @@ -26,16 +26,16 @@ title: 框架开发 在 Agent Worker 启动的时候会实例化 Agent,而在 App Worker 启动时会实例化 Application,这两个类又同时继承 [EggCore](https://github.com/eggjs/egg-core)。 -EggCore 可以看做 koa Application 的升级版,默认内置 [Loader](./loader.md)、[Router](../basics/router.md) 及应用异步启动等功能,可以看做是支持 Loader 的 koa。 +EggCore 可以看做 Koa Application 的升级版,默认内置 [Loader](./loader.md)、[Router](../basics/router.md) 及应用异步启动等功能,可以看做是支持 Loader 的 Koa。 ``` - koa Application + Koa Application ^ EggCore ^ ┌──────┴───────┐ │ │ - egg Agent egg Application + Egg Agent Egg Application ^ ^ agent worker app worker ``` @@ -55,11 +55,11 @@ $ npm test ### 框架 API -egg 框架提供了一些 API,所有继承的框架都需要提供,只增不减。这些 API 基本都有 Agent 和 Application 两份。 +Egg 框架提供了一些 API,所有继承的框架都需要提供,只增不减。这些 API 基本都有 Agent 和 Application 两份。 #### `egg.startCluster` -egg 的多进程启动器,由这个方法来启动 Master,主要的功能实现在 [egg-cluster](https://github.com/eggjs/egg-cluster) 上。所以直接使用 EggCore 还是单进程的方式,而 egg 实现了多进程。 +Egg 的多进程启动器,由这个方法来启动 Master,主要的功能实现在 [egg-cluster](https://github.com/eggjs/egg-cluster) 上。所以直接使用 EggCore 还是单进程的方式,而 Egg 实现了多进程。 ```js const startCluster = require('egg').startCluster; @@ -77,17 +77,17 @@ startCluster({ #### `egg.Application` 和 `egg.Agent` -进程中的唯一单例,但 Application 和 Agent 存在一定差异。如果框架继承于 egg,会定制这两个类,那 framework 应该 export 这两个类。 +进程中的唯一单例,但 Application 和 Agent 存在一定差异。如果框架继承于 Egg,会定制这两个类,那 framework 应该 export 这两个类。 #### `egg.AppWorkerLoader` 和 `egg.AgentWorkerLoader` -框架也存在定制 Loader 的场景,覆盖原方法或者新加载目录都需要提供自己的 Loader,而且必须要继承 egg 的 Loader。 +框架也存在定制 Loader 的场景,覆盖原方法或者新加载目录都需要提供自己的 Loader,而且必须要继承 Egg 的 Loader。 ### 框架继承 -框架支持继承关系,可以把框架比作一个类,那么基类就是 egg 框架,如果想对 egg 做扩展就继承。 +框架支持继承关系,可以把框架比作一个类,那么基类就是 Egg 框架,如果想对 Egg 做扩展就继承。 -首先定义一个框架需要实现 egg 所有的 API +首先定义一个框架需要实现 Egg 所有的 API ```js // package.json @@ -108,7 +108,7 @@ Object.assign(exports, egg); ```js // index.js -// 覆盖了 egg 的 Application +// 覆盖了 Egg 的 Application exports.Application = require('./lib/application.js'); // lib/application.js @@ -145,7 +145,7 @@ module.exports = YadanApplication; 现在的实现方案是基于类继承的,每一层框架都必须继承上一层框架并且指定 eggPath,然后遍历原型链就能获取每一层的框架路径了。 -比如有三层框架:部门框架(department)> 企业框架(enterprise)> egg +比如有三层框架:部门框架(department)> 企业框架(enterprise)> Egg ```js // enterprise @@ -173,11 +173,11 @@ const app = new Application(); app.ready(); ``` -以上均是伪代码,为了详细说明框架路径的加载过程,不过 egg 已经在[本地开发](../core/development.md)和[应用部署](./deployment.md)提供了很好的工具,不需要自己实现。 +以上均是伪代码,为了详细说明框架路径的加载过程,不过 Egg 已经在[本地开发](../core/development.md)和[应用部署](./deployment.md)提供了很好的工具,不需要自己实现。 ### 自定义 Agent -上面的例子自定义了 Application,因为 egg 是多进程模型,所以还需要定义 Agent,原理是一样的。 +上面的例子自定义了 Application,因为 Egg 是多进程模型,所以还需要定义 Agent,原理是一样的。 ```js // index.js @@ -219,7 +219,7 @@ class YadanApplication extends Application { get [EGG_PATH]() { return path.dirname(__dirname); } - // 覆盖 egg 的 Loader,启动时使用这个 Loader + // 覆盖 Egg 的 Loader,启动时使用这个 Loader get [EGG_LOADER]() { return AppWorkerLoader; } @@ -236,7 +236,7 @@ class YadanAppWorkerLoader extends AppWorkerLoader { module.exports = YadanAppWorkerLoader; ``` -AgentWorkerLoader 扩展也类似,这里不再举例。AgentWorkerLoader 加载的文件可以于 AppWorkerLoader 不同,比如 默认加载时,egg 的 AppWorkerLoader 会加载 `app.js` 而 AgentWorkerLoader 加载的是 `agent.js`。 +AgentWorkerLoader 扩展也类似,这里不再举例。AgentWorkerLoader 加载的文件可以于 AppWorkerLoader 不同,比如 默认加载时,Egg 的 AppWorkerLoader 会加载 `app.js` 而 AgentWorkerLoader 加载的是 `agent.js`。 ## 框架启动原理 @@ -328,7 +328,7 @@ describe('/test/index.test.js', () => { 很少场景会使用多进程测试,因为多进程无法进行 API 级别的 mock 导致测试成本很高,而进程在有覆盖率的场景启动很慢,测试会超时。但多进程测试是验证多进程模型最好的方式,还可以测试 stdout 和 stderr。 -多进程测试和 `mm.app` 参数一致,但 app 的 API 完全不同,不过 supertest 依然可用。 +多进程测试和 `mm.app` 参数一致,但 app 的 API 完全不同,不过 SuperTest 依然可用。 ```js const mock = require('egg-mock'); diff --git a/docs/source/zh-cn/advanced/loader.md b/docs/source/zh-cn/advanced/loader.md index 4d4e1470a2..f1015e765e 100644 --- a/docs/source/zh-cn/advanced/loader.md +++ b/docs/source/zh-cn/advanced/loader.md @@ -1,11 +1,11 @@ title: Loader --- -egg 在 koa 的基础上进行增强最重要的就是基于一定的约定,根据功能差异将代码放到不同的目录下管理,对整体团队的开发成本提升有着明显的效果。Loader 实现了这套约定,并抽象了很多底层 API 可以进一步扩展。 +Egg 在 Koa 的基础上进行增强最重要的就是基于一定的约定,根据功能差异将代码放到不同的目录下管理,对整体团队的开发成本提升有着明显的效果。Loader 实现了这套约定,并抽象了很多底层 API 可以进一步扩展。 ## 应用、框架和插件 -egg 是一个底层框架,应用可以直接使用,但 egg 本身的插件比较少,应用需要自己配置插件增加各种特性,比如 MySQL。 +Egg 是一个底层框架,应用可以直接使用,但 Egg 本身的插件比较少,应用需要自己配置插件增加各种特性,比如 MySQL。 ```js // 应用配置 @@ -26,7 +26,7 @@ module.exports = { } ``` -当应用达到一定数量,我们会发现大部分应用的配置都是类似的,这时可以基于 egg 扩展出一个框架,应用的配置就会简化很多。 +当应用达到一定数量,我们会发现大部分应用的配置都是类似的,这时可以基于 Egg 扩展出一个框架,应用的配置就会简化很多。 ```js // 框架配置 @@ -72,7 +72,7 @@ module.exports = { - 我们在应用中完成业务,需要指定一个框架才能运行起来,当需要某个特性场景的功能时可以配置插件(比如 MySQL)。 - 插件只完成特定功能,当两个独立的功能有互相依赖时,还是分开两个插件,但需要配置依赖。 -- 框架是一个启动器(默认就是 egg),必须有它才能运行起来。框架还是一个封装器,将插件的功能聚合起来统一提供,框架也可以配置插件。 +- 框架是一个启动器(默认就是 Egg),必须有它才能运行起来。框架还是一个封装器,将插件的功能聚合起来统一提供,框架也可以配置插件。 - 在框架的基础上还可以扩展出新的框架,也就是说**框架是可以无限级继承的**,有点像类的继承。 ``` @@ -83,15 +83,15 @@ module.exports = { + | framework1 +--------------+ plugin | | | | framework2 | | + +--------------+--------------+ | -| egg | | +| Egg | | +-----------------------------------+--------| -| koa | +| Koa | +-----------------------------------+--------+ ``` ## loadUnit -egg 将应用、框架和插件都称为加载单元(loadUnit),因为在代码结构上几乎没有什么差异,下面是目录结构 +Egg 将应用、框架和插件都称为加载单元(loadUnit),因为在代码结构上几乎没有什么差异,下面是目录结构 ``` loadUnit @@ -132,7 +132,7 @@ config/config.{env}.js | ✔︎ | ✔︎ | ✔︎ config/plugin.js | ✔︎ | ✔︎ | package.json | ✔︎ | ✔︎ | ✔︎ -在加载过程中,egg 会遍历所有的 loadUnit 加载上述的文件(应用、框架、插件各有不同),加载时有一定的优先级 +在加载过程中,Egg 会遍历所有的 loadUnit 加载上述的文件(应用、框架、插件各有不同),加载时有一定的优先级 - 按插件 => 框架 => 应用依次加载 - 插件之间的顺序由依赖关系决定,被依赖方先加载,无依赖按 object key 配置顺序加载,具体可以查看[插件章节](./plugin.md) @@ -166,7 +166,7 @@ plugin1 为 framework1 依赖的插件,配置合并后 object key 的顺序会 ### 文件顺序 -上面已经列出了默认会加载的文件,egg 会按如下文件顺序加载,每个文件或目录再根据 loadUnit 的顺序去加载(应用、框架、插件各有不同)。 +上面已经列出了默认会加载的文件,Egg 会按如下文件顺序加载,每个文件或目录再根据 loadUnit 的顺序去加载(应用、框架、插件各有不同)。 - 加载 [plugin](./plugin.md),找到应用和框架,加载 `config/plugin.js` - 加载 [config](../basics/config.md), 遍历 loadUnit 加载 `config/config.{env}.js` @@ -212,7 +212,7 @@ Loader 还提供了 [caseStyle](#caseStyle-boolean) 强制指定首字母大小 - loadController() - loadRouter() -egg 基于 Loader 实现了 [AppWorkerLoader] 和 [AgentWorkerLoader],上层框架基于这两个类来扩展,**Loader 的扩展只能在框架进行**。 +Egg 基于 Loader 实现了 [AppWorkerLoader] 和 [AgentWorkerLoader],上层框架基于这两个类来扩展,**Loader 的扩展只能在框架进行**。 ```js // 自定义 AppWorkerLoader @@ -240,7 +240,7 @@ class CustomAppWorkerLoader extends AppWorkerLoader { exports.AppWorkerLoader = CustomAppWorkerLoader; // index.js -// 拷贝一份 egg 的 API +// 拷贝一份 Egg 的 API Object.assign(exports, require('egg')); // 将自定义的 Loader exports 出来 exports.AppWorkerLoader = require('./lib/loader').AppWorkerLoader; diff --git a/docs/source/zh-cn/advanced/plugin.md b/docs/source/zh-cn/advanced/plugin.md index f7cc1957c3..75b2a97bf4 100644 --- a/docs/source/zh-cn/advanced/plugin.md +++ b/docs/source/zh-cn/advanced/plugin.md @@ -4,7 +4,7 @@ title: 插件开发 插件机制是我们框架的一大特色。它不但可以保证框架核心的足够精简、稳定、高效,还可以促进业务逻辑的复用,生态圈的形成。有人可能会问了 -> koa 已经有了中间件的机制,为啥还要插件呢? +> Koa 已经有了中间件的机制,为啥还要插件呢? > 中间件、插件、应用它们之间是什么关系,有什么区别? > 我该怎么使用一个插件? > 如何编写一个插件? @@ -14,7 +14,7 @@ title: 插件开发 ## 为什么要插件 -我们在使用 koa 中间件过程中发现了下面一些问题: +我们在使用 Koa 中间件过程中发现了下面一些问题: 1. 中间件加载其实是有先后顺序的,但是中间件自身却无法管理这种顺序,只能交给使用者。这样其实非常不友好,一旦顺序不对,结果可能有天壤之别。 2. 中间件的定位是拦截用户请求,并在它前后做一些事情,例如:鉴权、安全检查、访问日志等等。但实际情况是,有些功能是和请求无关的,例如:定时任务、消息订阅、后台逻辑等等。 @@ -66,7 +66,7 @@ title: 插件开发 - `{String} name` - 插件名(必须配置),具有唯一性,配置依赖关系时会指定依赖插件的 name。 - `{Array} dependencies` - 当前插件强依赖的插件列表(如果依赖的插件没找到,应用启动失败)。 - `{Array} optionalDependencies` - 当前插件的可选依赖插件列表(如果依赖的插件未开启,只会 warning,不会影响应用启动)。 - - `{Array} env` - 只有在指定运行环境才能开启,具体有哪些环境可以参考 [运行环境](../basics/env.md)。此配置是可选的,一般情况下都不需要配置。 + - `{Array} env` - 只有在指定运行环境才能开启,具体有哪些环境可以参考[运行环境](../basics/env.md)。此配置是可选的,一般情况下都不需要配置。 ```json { @@ -129,12 +129,12 @@ title: 插件开发 在插件相应的文件内对框架内置对象进行扩展,和应用一样 -- `app/extend/request.js` - 扩展 koa#Request 对象 -- `app/extend/response.js` - 扩展 koa#Response 对象 -- `app/extend/context.js` - 扩展 koa#Context 对象 -- `app/extend/helper.js ` - 扩展 Helper 对象 -- `app/extend/application.js` - 扩展 app 对象 -- `app/extend/agent.js` - 扩展 agent 对象 +- `app/extend/request.js` - 扩展 Koa#Request 类 +- `app/extend/response.js` - 扩展 Koa#Response 类 +- `app/extend/context.js` - 扩展 Koa#Context 类 +- `app/extend/helper.js ` - 扩展 Helper 类 +- `app/extend/application.js` - 扩展 Application 类 +- `app/extend/agent.js` - 扩展 Agent 类 ### 插入自定义中间件 @@ -450,7 +450,7 @@ exports.onerror = false; 框架已内置插件列表: - [onerror](https://github.com/eggjs/egg-onerror) 统一异常处理 -- [session](https://github.com/eggjs/egg-session) session 实现 +- [Session](https://github.com/eggjs/egg-session) Session 实现 - [i18n](https://github.com/eggjs/egg-i18n) 多语言 - [watcher](https://github.com/eggjs/egg-watcher) 文件和文件夹监控 - [multipart](https://github.com/eggjs/egg-multipart) 文件流式上传 @@ -545,11 +545,11 @@ $ npm test ## 为何不使用 npm 包名来做插件名? -egg 是通过 `eggPlugin.name` 来定义插件名的,只在应用或框架具备唯一性,也就是说**多个 npm 包可能有相同的插件名**,为什么这么设计呢? +Egg 是通过 `eggPlugin.name` 来定义插件名的,只在应用或框架具备唯一性,也就是说**多个 npm 包可能有相同的插件名**,为什么这么设计呢? -首先 egg 插件不仅仅支持 npm 包,还支持通过目录来找插件。在[渐进式开发](../tutorials/progressive.md)章节提到如何使用这两个配置来进行代码演进。目录对单元测试也比较友好。所以 egg 无法通过 npm 的包名来做唯一性。 +首先 Egg 插件不仅仅支持 npm 包,还支持通过目录来找插件。在[渐进式开发](../tutorials/progressive.md)章节提到如何使用这两个配置来进行代码演进。目录对单元测试也比较友好。所以 Egg 无法通过 npm 的包名来做唯一性。 -更重要的是 egg 可以使用这种特性来做适配器。比如[模板开发规范](./view-plugin.md#插件命名规范)定义的插件名为 view,而存在 `egg-view-nunjucks`,`egg-view-react` 等插件,使用者只需要更换插件和修改模板,不需要动 Controller, 因为所有的模板插件都实现了相同的 API。 +更重要的是 Egg 可以使用这种特性来做适配器。比如[模板开发规范](./view-plugin.md#插件命名规范)定义的插件名为 view,而存在 `egg-view-nunjucks`,`egg-view-react` 等插件,使用者只需要更换插件和修改模板,不需要动 Controller, 因为所有的模板插件都实现了相同的 API。 **将相同功能的插件赋予相同的插件名,具备相同的 API,可以快速切换**。这在模板、数据库等领域非常适用。 diff --git a/docs/source/zh-cn/advanced/view-plugin.md b/docs/source/zh-cn/advanced/view-plugin.md index 4aa2c5f355..878716622f 100644 --- a/docs/source/zh-cn/advanced/view-plugin.md +++ b/docs/source/zh-cn/advanced/view-plugin.md @@ -155,7 +155,7 @@ module.exports = class MyCustomView { render(filename, locals) { locals.helper = new ViewHelper(this.ctx); - // 调用 nunjucks render + // 调用 Nunjucks render } } ``` diff --git a/docs/source/zh-cn/basics/app-start.md b/docs/source/zh-cn/basics/app-start.md index c1ba9bd685..afa84118de 100644 --- a/docs/source/zh-cn/basics/app-start.md +++ b/docs/source/zh-cn/basics/app-start.md @@ -3,7 +3,7 @@ title: 启动自定义 我们常常需要在应用启动期间进行一些初始化工作,等初始化完成后应用才可以启动成功,并开始对外提供服务。 -框架提供了统一的入口文件(`app.js`)进行启动过程自定义,这个文件只返回一个函数。例如,我们需要在应用启动期间从远程接口加载一份全国城市列表,以便于后续在 controller 中使用: +框架提供了统一的入口文件(`app.js`)进行启动过程自定义,这个文件只返回一个函数。例如,我们需要在应用启动期间从远程接口加载一份全国城市列表,以便于后续在 Controller 中使用: ```js // app.js @@ -18,7 +18,7 @@ module.exports = app => { }; ``` -在 controller 中就可以使用了: +在 Controller 中就可以使用了: ```js // app/controller/city.js diff --git a/docs/source/zh-cn/basics/config.md b/docs/source/zh-cn/basics/config.md index a7b48e9cf8..de6d7d08a9 100644 --- a/docs/source/zh-cn/basics/config.md +++ b/docs/source/zh-cn/basics/config.md @@ -1,8 +1,6 @@ -title: 配置 +title: Config 配置 --- -## config 配置 - 框架提供了强大且可扩展的配置功能,可以自动合并应用、插件、框架的配置,按顺序覆盖,且可以根据环境维护不同的配置。合并后的配置可直接从 `app.config` 获取。 配置的管理有多种方案,以下列一些常见的方案 @@ -28,7 +26,7 @@ config `config.default.js` 为默认的配置文件,所有环境都会加载这个配置文件,一般也会作为开发环境的默认配置文件。 -当指定 env 时会同时加载对应的配置文件,并覆盖默认配置文件的同名配置。如 prod 环境会加载 `config.prod.js` 和 `config.default.js` 文件,`config.prod.js` 会覆盖 `config.default.js` 的同名配置。 +当指定 env 时会同时加载对应的配置文件,并覆盖默认配置文件的同名配置。如 `prod` 环境会加载 `config.prod.js` 和 `config.default.js` 文件,`config.prod.js` 会覆盖 `config.default.js` 的同名配置。 ### 配置写法 @@ -132,7 +130,7 @@ module.exports = { 框架默认内置了企业级应用常用的[一部分插件](https://github.com/eggjs/egg/blob/master/config/plugin.js)。 -而应用开发者可以根据业务需求,引入其他插件,只需要指定 package 配置。 +而应用开发者可以根据业务需求,引入其他插件,只需要指定 `package` 配置。 ```js // 使用 mysql 插件 @@ -144,7 +142,7 @@ module.exports = { }; ``` -package 为一个 npm 模块,必须添加依赖到 `pkg.dependencies` 中。框架会在 node_modules 目录中找到这个模块作为插件入口。 +`package` 为一个 npm 模块,必须添加依赖到 `pkg.dependencies` 中。框架会在 node_modules 目录中找到这个模块作为插件入口。 ```json { @@ -174,7 +172,7 @@ path 为一个绝对路径,这样应用可以把自己写的插件直接放到 框架在启动时会把合并后的最终配置 dump 到 `run/application_config.json`(worker 进程)和 `run/agent_config.json`(agent 进程)中,可以用来分析问题。 -配置文件中会隐藏一些字段,主要包括两类 +配置文件中会隐藏一些字段,主要包括两类: - 如密码、密钥等安全字段,这里可以通过 `config.dump.ignore` 配置,必须是 [Set] 类型,查看[默认配置](https://github.com/eggjs/egg/blob/master/config/config.default.js)。 - 如函数、Buffer 等类型,`JSON.stringify` 后的内容特别大 diff --git a/docs/source/zh-cn/basics/controller.md b/docs/source/zh-cn/basics/controller.md index d322fdd38f..65e21f44e3 100644 --- a/docs/source/zh-cn/basics/controller.md +++ b/docs/source/zh-cn/basics/controller.md @@ -1,30 +1,30 @@ title: controller --- -## 什么是 controller +## 什么是 Controller -[前面章节](./router.md)写到,我们通过 router 将用户的请求基于 method 和 URL 分发到了对应的 controller 上,那 controller 负责做什么? +[前面章节](./router.md)写到,我们通过 Router 将用户的请求基于 method 和 URL 分发到了对应的 Controller 上,那 Controller 负责做什么? -简单的说 controller 负责**解析用户的输入,处理后返回相应的结果**,例如 +简单的说 Controller 负责**解析用户的输入,处理后返回相应的结果**,例如 -- 在 [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer) 接口中,controller 接受用户的参数,从数据库中查找内容返回给用户或者将用户的请求更新到数据库中。 -- 在 html 页面请求中,controller 根据用户访问不同的 URL,渲染不同的模板得到 html 返回给用户。 -- 在代理服务器中,controller 将用户的请求转发到其他服务器上,并将其他服务器的处理结果返回给用户。 +- 在 [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer) 接口中,Controller 接受用户的参数,从数据库中查找内容返回给用户或者将用户的请求更新到数据库中。 +- 在 HTML 页面请求中,Controller 根据用户访问不同的 URL,渲染不同的模板得到 HTML 返回给用户。 +- 在代理服务器中,Controller 将用户的请求转发到其他服务器上,并将其他服务器的处理结果返回给用户。 -框架推荐 controller 层主要对用户的请求参数进行处理(校验、转换),然后调用对应的 [service](./service.md) 方法处理业务,得到业务结果后封装并返回: +框架推荐 Controller 层主要对用户的请求参数进行处理(校验、转换),然后调用对应的 [service](./service.md) 方法处理业务,得到业务结果后封装并返回: 1. 获取用户通过 HTTP 传递过来的请求参数。 1. 校验、组装参数。 -1. 调用 service 进行业务处理,必要时处理转换 service 的返回结果,让它适应用户的需求。 +1. 调用 Service 进行业务处理,必要时处理转换 Service 的返回结果,让它适应用户的需求。 1. 通过 HTTP 将结果响应给用户。 -## 如何编写 controller +## 如何编写 Controller -所有的 controller 文件都必须放在 `app/controller` 目录下。controller 支持多种形式进行编写,可以根据不同的项目场景和开发习惯来选择。 +所有的 Controller 文件都必须放在 `app/controller` 目录下。Controller 支持多种形式进行编写,可以根据不同的项目场景和开发习惯来选择。 -### controller 类(推荐) +### Controller 类(推荐) -我们可以通过定义 controller 类的方式来编写代码: +我们可以通过定义 Controller 类的方式来编写代码: ```js // app/controller/post.js @@ -41,7 +41,7 @@ module.exports = app => { // 组装参数 const author = ctx.session.userId; const req = Object.assign(ctx.request.body, { author }); - // 调用 service 进行业务处理 + // 调用 Service 进行业务处理 const res = yield service.post.create(req); // 设置响应内容和响应状态码 ctx.body = { id: res.id }; @@ -53,7 +53,7 @@ module.exports = app => { } ``` -我们通过上面的代码定义了一个 `PostController` 的类,类里面的每一个方法都可以作为一个 controller 在 router 中引用到。 +我们通过上面的代码定义了一个 `PostController` 的类,类里面的每一个方法都可以作为一个 Controller 在 Router 中引用到。 ```js // app/router.js @@ -62,18 +62,18 @@ module.exports = { } ``` -定义的 controller 类,会在每一个请求访问到 server 时实例化一个全新的对象,而项目中的 controller 类继承于 `app.Controller`,会有下面几个属性挂在 `this` 上。 +定义的 Controller 类,会在每一个请求访问到 server 时实例化一个全新的对象,而项目中的 Controller 类继承于 `app.Controller`,会有下面几个属性挂在 `this` 上。 - `this.ctx`: 当前请求的上下文 [Context](./extend.md#context) 对象的实例,通过它我们可以拿到框架封装好的处理当前请求的各种便捷属性和方法。 - `this.app`: 当前应用 [Application](./extend.md#application) 对象的实例,通过它我们可以拿到框架提供的全局对象和方法。 -- `this.service`:应用定义的 [service](./service.md),通过它我们可以访问到抽象出的业务层。 +- `this.service`:应用定义的 [Service](./service.md),通过它我们可以访问到抽象出的业务层。 - `this.config`:应用运行时的[配置项](./config.md)。 #### 自定义 Controller 基类 -按照类的方式编写 controller,不仅可以让我们更好的对 controller 层代码进行抽象(例如将一些统一的处理抽象成一些私有方法),还可以通过自定义 controller 基类的方式封装应用中常用的方法。 +按照类的方式编写 Controller,不仅可以让我们更好的对 Controller 层代码进行抽象(例如将一些统一的处理抽象成一些私有方法),还可以通过自定义 Controller 基类的方式封装应用中常用的方法。 -在[启动自定义](./app-start.md)中,应用可自己定义 controller 基类,这样在 `app/controller` 中编写 controller 时就可以使用到定义在基类上的这些方法了。 +在[启动自定义](./app-start.md)中,应用可自己定义 Controller 基类,这样在 `app/controller` 中编写 Controller 时就可以使用到定义在基类上的这些方法了。 ```js // app.js @@ -99,7 +99,7 @@ module.exports = app => { } ``` -此时在编写应用的 controller 时,可以直接使用基类上的方法: +此时在编写应用的 Controller 时,可以直接使用基类上的方法: ```js //app/controller/post.js @@ -113,11 +113,11 @@ module.exports = app => { }; ``` -### controller 方法 +### Controller 方法 -每一个 controller 都是一个 generator function,它的第一个参数是请求的上下文 [Context](./extend.md#context) 对象的实例,通过它我们可以拿到框架封装好的各种便捷属性和方法。 +每一个 Controller 都是一个 generator function,它的第一个参数是请求的上下文 [Context](./extend.md#context) 对象的实例,通过它我们可以拿到框架封装好的各种便捷属性和方法。 -例如我们写一个对应到 `POST /api/posts` 接口的 controller,我们会在 `app/controller` 目录下创建一个 `post.js` 文件 +例如我们写一个对应到 `POST /api/posts` 接口的 Controller,我们会在 `app/controller` 目录下创建一个 `post.js` 文件 ```js // app/controller/post.js @@ -143,9 +143,9 @@ exports.create = function* (ctx) { ## HTTP 基础 -由于 controller 基本上是业务开发中唯一和 HTTP 协议打交道的地方,在继续往下了解之前,我们首先简单的看一下 HTTP 协议是怎样的。 +由于 Controller 基本上是业务开发中唯一和 HTTP 协议打交道的地方,在继续往下了解之前,我们首先简单的看一下 HTTP 协议是怎样的。 -如果我们发起一个 HTTP 请求来访问前面例子中提到的 controller: +如果我们发起一个 HTTP 请求来访问前面例子中提到的 Controller: ``` curl -X POST http://localhost:3000/api/posts --data '{"title":"controller", "content": "what is controller"}' --header 'Content-Type:application/json; charset=UTF-8' @@ -166,9 +166,9 @@ Content-Type: application/json; charset=UTF-8 - method:这个请求中 method 的值是 `POST`。 - path:值为 `/api/posts`,如果用户的请求中包含 query,也会在这里出现 -从第二行开始直到遇到的第一个空行位置,都是请求的 headers 部分,这一部分中有许多常用的属性,包括这里看到的 Host,Content-Type,还有 `Cookie`,`User-Agent` 等等。在这个请求中有两个头: +从第二行开始直到遇到的第一个空行位置,都是请求的 Headers 部分,这一部分中有许多常用的属性,包括这里看到的 Host,Content-Type,还有 `Cookie`,`User-Agent` 等等。在这个请求中有两个头: -- `Host`:我们在浏览器发起请求的时候,域名会用来通过 DNS 解析找到服务的 ip 地址,但是浏览器也会将域名和端口号放在 Host 头中一并发送给服务端。 +- `Host`:我们在浏览器发起请求的时候,域名会用来通过 DNS 解析找到服务的 IP 地址,但是浏览器也会将域名和端口号放在 Host 头中一并发送给服务端。 - `Content-Type`:当我们的请求有 body 的时候,都会有 Content-Type 来标明我们的请求体是什么格式的。 之后的内容全部都是请求的 body,当请求是 POST, PUT, DELETE 等方法的时候,可以带上请求体,服务端会根据 Content-Type 来解析请求体。 @@ -187,17 +187,17 @@ Connection: keep-alive 第一行中也包含了三段,其中我们常用的主要是[响应状态码](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes),这个例子中它的值是 201,它的含义是在服务端成功创建了一条资源。 -和请求一样,从第二行开始到下一个空行之间都是响应头,这里的 Content-Type, Content-Length 表示这个响应的格式是 json,长度为 8 个字符。 +和请求一样,从第二行开始到下一个空行之间都是响应头,这里的 Content-Type, Content-Length 表示这个响应的格式是 JSON,长度为 8 个字符。 最后剩下的部分就是这次响应真正的内容。 ## 获取 HTTP 请求参数 -从上面的 HTTP 请求示例中可以看到,有好多地方可以放用户的请求数据,框架通过在 controller 上绑定的 context 实例,提供了许多便捷方法和属性获取用户通过 HTTP 请求发送过来的参数。 +从上面的 HTTP 请求示例中可以看到,有好多地方可以放用户的请求数据,框架通过在 Controller 上绑定的 Context 实例,提供了许多便捷方法和属性获取用户通过 HTTP 请求发送过来的参数。 ### query -在 URL 中 `?` 后面的部分是一个 query string,这一部分经常用于 GET 类型的请求中传递参数。例如 `GET /posts?category=egg&language=node` 中 `category=egg&language=node` 就是用户传递过来的参数。我们可以通过 `context.query` 拿到解析过后的这个参数体 +在 URL 中 `?` 后面的部分是一个 Query String,这一部分经常用于 GET 类型的请求中传递参数。例如 `GET /posts?category=egg&language=node` 中 `category=egg&language=node` 就是用户传递过来的参数。我们可以通过 `context.query` 拿到解析过后的这个参数体 ```js exports.listPosts = function* (ctx) { @@ -209,9 +209,9 @@ exports.listPosts = function* (ctx) { }; ``` -当 query string 中的 key 重复时,`context.query` 只取 key 第一次出现时的值,后面再出现的都会被忽略。`GET /posts?category=egg&category=koa` 通过 `context.query` 拿到的值是 `{ category: 'egg' }`。 +当 Query String 中的 key 重复时,`context.query` 只取 key 第一次出现时的值,后面再出现的都会被忽略。`GET /posts?category=egg&category=koa` 通过 `context.query` 拿到的值是 `{ category: 'egg' }`。 -这样处理的原因是为了保持统一性,由于通常情况下我们都不会设计让用户传递 key 相同的 query string,所以我们经常会写类似下面的代码: +这样处理的原因是为了保持统一性,由于通常情况下我们都不会设计让用户传递 key 相同的 Query String,所以我们经常会写类似下面的代码: ```js const key = ctx.query.key || ''; @@ -220,11 +220,11 @@ if (key.startsWith('egg')) { } ``` -而如果有人故意发起请求在 query string 中带上重复的 key 来请求时就会引发系统异常。因此框架保证了从 `context.query` 上获取的参数一旦存在,一定是字符串类型。 +而如果有人故意发起请求在 Query String 中带上重复的 key 来请求时就会引发系统异常。因此框架保证了从 `context.query` 上获取的参数一旦存在,一定是字符串类型。 #### queries -有时候我们的系统会设计成让用户传递相同的 key,例如 `GET /posts?category=egg&id=1&id=2&id=3`。针对此类情况,框架提供了 `context.queries` 对象,这个对象也解析了 query string,但是它不会丢弃任何一个重复的数据,而是将他们都放到一个数组中: +有时候我们的系统会设计成让用户传递相同的 key,例如 `GET /posts?category=egg&id=1&id=2&id=3`。针对此类情况,框架提供了 `context.queries` 对象,这个对象也解析了 Query String,但是它不会丢弃任何一个重复的数据,而是将他们都放到一个数组中: ```js // GET /posts?category=egg&id=1&id=2&id=3 @@ -240,9 +240,9 @@ exports.listPosts = function* (ctx) { `context.queries` 上所有的 key 如果有值,也一定会是数组类型。 -### router params +### Router params -在 [router](./router.md) 中,我们介绍了 router 上也可以申明参数,这些参数都可以通过 `context.params` 获取到。 +在 [Router](./router.md) 中,我们介绍了 Router 上也可以申明参数,这些参数都可以通过 `context.params` 获取到。 ```js // app.get('/projects/:projectId/app/:appId', 'app.listApp'); @@ -261,7 +261,7 @@ exports.listApp = function* (ctx) { - [浏览器中会对 URL 的长度有所限制](http://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers),如果需要传递的参数过多就会无法传递。 - 服务端经常会将访问的完整 URL 记录到日志文件中,有一些敏感数据通过 URL 传递会不安全。 -在前面的 HTTP 请求报文示例中,我们看到在 header 之后还有一个 body 部分,我们通常会在这个部分传递 POST、PUT 和 DELETE 等方法的参数。一般请求中有 body 的时候,客户端(浏览器)会同时发送 `Content-Type` 告诉服务端这次请求的 body 是什么格式的。web 开发中数据传递最常用的两类格式分别是 json 和 form。 +在前面的 HTTP 请求报文示例中,我们看到在 header 之后还有一个 body 部分,我们通常会在这个部分传递 POST、PUT 和 DELETE 等方法的参数。一般请求中有 body 的时候,客户端(浏览器)会同时发送 `Content-Type` 告诉服务端这次请求的 body 是什么格式的。Web 开发中数据传递最常用的两类格式分别是 JSON 和 Form。 框架内置了 [bodyParser](https://github.com/koajs/bodyparser) 中间件来对这两类格式的请求 body 解析成 object 挂载到 `context.request.body` 上。HTTP 协议中并不建议在通过 GET、HEAD 方法访问时传递 body,所以我们无法在 GET、HEAD 方法中按照此方法获取到内容。 @@ -296,13 +296,13 @@ module.exports = { 如果用户的请求 body 超过了我们配置的解析最大长度,会抛出一个状态码为 `413` 的异常,如果用户请求的 body 解析失败(错误的 JSON),会抛出一个状态码为 `400` 的异常。 -**注意:在调整 bodyParser 支持的 body 长度时,如果我们应用前面还有一层反向代理(nginx),可能也需要调整它的配置,确保反向代理也支持同样长度的请求 body。** +**注意:在调整 bodyParser 支持的 body 长度时,如果我们应用前面还有一层反向代理(Nginx),可能也需要调整它的配置,确保反向代理也支持同样长度的请求 body。** ### 获取上传的文件 -请求 body 除了可以带参数之外,还可以发送文件,一般来说,浏览器上都是通过 `Multipart/form-data` 格式发送文件的,框架通过内置 [multipart](https://github.com/eggjs/egg-multipart) 插件来支持获取用户上传的文件。 +请求 body 除了可以带参数之外,还可以发送文件,一般来说,浏览器上都是通过 `Multipart/form-data` 格式发送文件的,框架通过内置 [Multipart](https://github.com/eggjs/egg-multipart) 插件来支持获取用户上传的文件。 -在 controller 中,我们可以通过 `context.getFileStream*()` 接口能获取到上传的文件流。 +在 Controller 中,我们可以通过 `context.getFileStream*()` 接口能获取到上传的文件流。 ```html