文章目录
- 🌟前言
- 🌟 框架内置对象
- 🌟Koa 继承对象
- 🌟Koa Application
- 🌟事件
- 🌟获取全局应用对象的方式
- 🌟全局应用对象的属性
- 🌟Context
- 🌟获取Context的方式
- 🌟Request & Response
- 🌟获取方式
- 🌟框架扩展对象
- 🌟Controller
- 🌟Service
- 🌟Helper
- 🌟获取方式
- 🌟自定义 helper 方法
- 🌟Config
- 🌟获取方式
- 🌟Logger
- 🌟写在最后
🌟前言
哈喽小伙伴们,新的专栏 Node 已开启;这个专栏里边会收录一些Node的基础知识和项目实战;今天我们继续带大家了解Node的框架 Egg
;让我们一起来看看吧🤘
🌟 框架内置对象
框架中内置的一些基础对象:
类型 | 描述 |
---|---|
Koa 继承对象 | Application, Context, Request, Response |
框架扩展对象 | Controller, Service, Helper, Config, Logger |
🌟Koa 继承对象
🌟Koa Application
Application
是全局应用对象,在一个应用中,只会实例化一个
,它继承自Koa.Application
,在它上面我们可以挂载一些全局的方法和对象。我们可以轻松的在插件或者应用中扩展 Application对象。
🌟事件
在框架运行时,会在 Application 实例上触发一些事件,应用开发者或者插件开发者可以监听这些事件做一些操作。作为应用开发者,我们一般会在启动自定义脚本中进行监听。
事件 | 描述 |
---|---|
server | 该事件一个 worker 进程只会触发一次,在 HTTP 服务完成启动后,会将 HTTP server 通过这个事件暴露出来给开发者。 |
error | 运行时有任何的异常被 onerror 插件捕获后,都会触发 error 事件,将错误对象和关联的上下文(如果有)暴露给开发者,可以进行自定义的日志记录上报等处理。 |
request 和 response | 应用收到请求和响应请求时,分别会触发 request 和 response 事件,并将当前请求上下文暴露出来,开发者可以监听这两个事件来进行日志记录。 |
// app.js
module.exports = app => {app.once('server', server => {// websocket});app.on('error', (err, ctx) => {// report error});app.on('request', ctx => {// log receive request});app.on('response', ctx => {// ctx.starttime is set by frameworkconst used = Date.now() - ctx.starttime;// log total cost});
};
🌟获取全局应用对象的方式
Application 对象(全局应用对象)几乎可以在编写应用时的任何一个地方获取到,下面介绍几个经常用到的获取方式:
几乎所有被框架 Loader 加载的文件(Controller,Service,Schedule 等),都可以 export 一个函数,这个函数会被 Loader 调用,并使用 app 作为参数:
- 启动自定义脚本
// app.js
module.exports = app => {// appapp.cache = new Cache();
};
- Controller、Service文件 在继承于 Controller, Service 基类的实例中,可以通过 this.app 访问到 Application 对象。
// app/controller/user.js
class UserController extends Controller {async fetch() {// this.appthis.ctx.body = this.app.cache.get(this.ctx.query.id);}
}
和 Koa 一样,在 Context 对象上,可以通过 ctx.app 访问到 Application 对象。以上面的 Controller 文件举例:
// app/controller/user.js
class UserController extends Controller {async fetch() {this.ctx.body = this.ctx.app.cache.get(this.ctx.query.id);}
}
🌟全局应用对象的属性
属性 | 类型 | 描述 |
---|---|---|
app.baseDir | String | 应用程序的根目录 |
app.config | Object | 应用程序的配置 |
app.env | String | app.env 等同于 app.config.env |
app.plugins | Object | 启用的插件列表 |
app.middleware | Object | 中间件列表 |
app.controller | Object | 控制器列表 |
app.router | Object | 获取路由对象 |
app.locals | Object | View的全局变量 |
🌟Context
Context 是一个请求级别的对象,继承自 Koa.Context
。在每一次收到用户请求时,框架会实例化一个 Context 对象
,这个对象封装了这次用户请求的信息,并提供了许多便捷的方法来获取请求参数或者设置响应信息。框架会将所有的 Service 挂载到 Context 实例上,一些插件也会将一些其他的方法和对象挂载到它上面(egg-sequelize 会将所有的 model 挂载在 Context 上)。
🌟获取Context的方式
最常见的 Context 实例获取方式是在 Middleware, Controller 以及 Service 中。Controller 中的获取方式在上面的例子中已经展示过了,在 Service 中获取和 Controller 中获取的方式一样,在 Middleware 中获取 Context 实例则和 Koa 框架在中间件中获取 Context 对象的方式一致。
Controller 中的获取Context:
// app/controller/user.js
class UserController extends Controller {async fetch() {// this.ctxthis.ctx.body = this.app.cache.get(this.ctx.query.id);}
}
在 Service 中获取和 Controller 中获取的方式一样:
// app/service/news.js
const Service = require('egg').Service;class NewsService extends Service {async list(page = 1) {// this.ctx 获取Context}
}
框架的 Middleware 同时支持 Koa v1 和 Koa v2 两种不同的中间件写法,根据不同的写法,获取 Context 实例的方式也稍有不同:
// Koa v1
function* middleware(next) {// this is instance of Contextconsole.log(this.query);yield next;
}// Koa v2
async function middleware(ctx, next) {// ctx is instance of Contextconsole.log(ctx.query);
}
在定时任务
中的每一个 task 都接受一个 Context 实例作为参数,以便我们更方便的执行一些定时的业务逻辑:
// app/schedule/refresh.js
exports.task = async ctx => {await ctx.service.posts.refresh();
};
🌟Request & Response
Request 是一个请求级别的对象,继承自 Koa.Request
。封装了 Node.js 原生的 HTTP Request
对象,提供了一系列辅助方法获取 HTTP 请求常用参数。
Response 是一个请求级别的对象,继承自 Koa.Response
。封装了 Node.js 原生的 HTTP Response 对象
,提供了一系列辅助方法设置 HTTP 响应。
🌟获取方式
可以在 Context 的实例上获取到当前请求的 Request(ctx.request)
和 Response(ctx.response)
实例。
// app/controller/user.js
class UserController extends Controller {async fetch() {const { app, ctx } = this;const id = ctx.request.query.id;ctx.response.body = app.cache.get(id);}
}
- Koa 会在 Context 上代理一部分 Request 和 Response 上的方法和属性,参见 Koa.Context。
- 如上面例子中的 ctx.request.query.id 和 ctx.query.id 是等价的,ctx.response.body= 和 ctx.body= 是等价的。
- 需要注意的是,获取 POST 的 body 应该使用 ctx.request.body,而不是 ctx.body。
🌟框架扩展对象
🌟Controller
框架提供了一个 Controller 基类,并推荐所有的 Controller 都继承于该基类实现。这个 Controller 基类有下列属性:
ctx
- 当前请求的 Context 实例。app
- 应用的 Application 实例。config
- 应用的配置。service
- 应用所有的 service。logger
- 为当前 controller 封装的 logger 对象。
在 Controller 文件中,可以通过两种方式来引用 Controller 基类:
// app/controller/user.js// 从 egg 上获取(推荐)
const Controller = require('egg').Controller;
class UserController extends Controller {// implement
}
module.exports = UserController;// 从 app 实例上获取
module.exports = app => {return class UserController extends app.Controller {// implement};
};
🌟Service
框架提供了一个 Service 基类,并推荐所有的 Service 都继承于该基类实现。
Service 基类的属性和 Controller 基类属性一致,访问方式也类似:
// app/service/user.js// 从 egg 上获取(推荐)
const Service = require('egg').Service;
class UserService extends Service {// implement
}
module.exports = UserService;// 从 app 实例上获取
module.exports = app => {return class UserService extends app.Service {// implement};
};
🌟Helper
Helper 用来提供一些实用的 utility 函数。它的作用在于我们可以将一些常用的动作抽离在 helper.js 里面成为一个独立的函数,这样可以用 JavaScript 来写复杂的逻辑,避免逻辑分散各处,同时可以更好的编写测试用例。
Helper 自身是一个类,有和 Controller 基类一样的属性,它也会在每次请求时进行实例化,因此 Helper 上的所有函数也能获取到当前请求相关的上下文信息。
🌟获取方式
可以在 Context 的实例上获取到当前请求的 Helper(ctx.helper) 实例。
// app/controller/user.js
class UserController extends Controller {async fetch() {const { app, ctx } = this;const id = ctx.query.id;const user = app.cache.get(id);ctx.body = ctx.helper.formatUser(user);}
}
除此之外,Helper 的实例还可以在模板中获取到,例如可以在模板中获取到 security 插件提供的 shtml 方法。
// app/view/home.nj
{{ helper.shtml(value) }}
🌟自定义 helper 方法
应用开发中,我们可能经常要自定义一些 helper 方法,例如上面例子中的 formatUser,我们可以通过框架扩展的形式来自定义 helper 方法。
// app/extend/helper.js
module.exports = {formatUser(user) {return only(user, ['name', 'phone']);},
};
🌟Config
我们推荐应用开发遵循配置和代码分离的原则,将一些需要硬编码的业务配置都放到配置文件中,同时配置文件支持各个不同的运行环境使用不同的配置,使用起来也非常方便,所有框架、插件和应用级别的配置都可以通过 Config 对象获取到
🌟获取方式
我们可以通过 app.config
从 Application 实例上获取到 config 对象,在 Controller, Service, Helper 的实例上通过 this.config
获取到 config 对象。
🌟Logger
框架内置了功能强大的日志功能,可以非常方便的打印各种级别的日志到对应的日志文件中,每一个 logger 对象都提供了 4 个级别的方法:
- logger.debug()
- logger.info()
- logger.warn()
- logger.error()
🌟写在最后
更多Node知识以及API请大家持续关注,尽请期待。各位小伙伴让我们 let’s be prepared at all times!
✨原创不易,还希望各位大佬支持一下!
👍 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!