Service

简单来说,Service 就是在复杂业务场景下用于做业务逻辑封装的一个抽象层,提供这个抽象有以下几个好处:

# 使用场景

# 定义 Service

// app/service/user.js
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;

# 属性

每一次用户请求,框架都会实例化对应的 Service 实例,由于它继承于 egg.Service,故拥有下列属性方便我们进行开发:

# Service ctx 详解

为了可以获取用户请求的链路,我们在 Service 初始化中,注入了请求上下文, 用户在方法中可以直接通过 this.ctx 来获取上下文相关信息。关于上下文的具体详解可以参看 Context, 有了 ctx 我们可以拿到框架给我们封装的各种便捷属性和方法。比如我们可以用:

# 注意事项

# 使用 Service

下面就通过一个完整的例子,看看怎么使用 Service。

// app/router.js
module.exports = app => {
app.router.get('/user/:id', app.controller.user.info);
};

// app/controller/user.js
const Controller = require('egg').Controller;
class UserController extends Controller {
async info() {
const userId = ctx.params.id;
const userInfo = await ctx.service.user.find(userId);
ctx.body = userInfo;
}
}
module.exports = UserController;

// app/service/user.js
const Service = require('egg').Service;
class UserService extends Service {
// 默认不需要提供构造函数。
// constructor(ctx) {
// super(ctx); 如果需要在构造函数做一些处理,一定要有这句话,才能保证后面 `this.ctx`的使用。
// // 就可以直接通过 this.ctx 获取 ctx 了
// // 还可以直接通过 this.app 获取 app 了
// }
async find(uid) {
// 假如 我们拿到用户 id 从数据库获取用户详细信息
const user = await this.ctx.db.query('select * from user where uid = ?', uid);

// 假定这里还有一些复杂的计算,然后返回需要的信息。
const picture = await this.getPicture(uid);

return {
name: user.user_name,
age: user.age,
picture,
};
}

async getPicture(uid) {
const result = await this.ctx.curl(`http://photoserver/uid=${uid}`, { dataType: 'json' });
return result.data;
}
}
module.exports = UserService;

// curl http://127.0.0.1:7001/user/1234