Service 层
Service 层的作用
Service 是具体业务逻辑的实现,一个封装好的 Service 可供多个 Controller 调用,而一个 Controller 里面也可以调用多个 Service,虽然在 Controller 中也可以写业务逻辑,但是并不建议这么做,代码中应该保持 Controller 逻辑简洁,仅仅发挥「桥梁」作用。
Controller 可以调用任何一个 Service 上的任何方法,值得注意的是:Service 是懒加载的,即只有当访问到它的时候框架才会去实例化它。
通常情况下,在 Service 中会做如下几件事情:
处理复杂业务逻辑:
- 调用数据库或第三方服务(例如 GitHub 信息获取等)
简单案例
一个简单的 Service 示例,将数据库中的查询结果返回出去:
js
// app/service/user.js
"use strict";
const { Service } = require("egg").Service;
class UserService extends Service {
async find(uid) {
const user = await this.ctx.db.query(
"select * from user where uid = ?",
uid
);
return user;
}
}
module.exports = UserService;
在 Controller 中可以直接调用:
js
class UserController extends Controller {
async info() {
const { ctx } = this;
const userId = ctx.params.id;
const userInfo = await ctx.service.user.find(userId);
ctx.body = userInfo;
}
}
INFO
注意,Service 文件必须放在 app/service
目录,支持多级目录,访问的时候可以通过目录名级联访问:
app/service/biz/user.js => ctx.service.biz.user app/service/sync_user.js => ctx.service.syncUser app/service/HackerNews.js => ctx.service.hackerNews
Service 里面的函数,可以理解为某个具体业务逻辑的最小单元,Service 里面也可以调用其他 Service,值得注意的是:Service 不是单例,是 请求级别 的对象,框架在每次请求中首次访问 ctx.service.xx 时延迟实例化,所以 Service 中可以通过 this.ctx 获取到当前请求的上下文。