Eggjs入门使用

1,554 阅读3分钟

前言

国有国法,家有家规,当我们一群人共同在做一件事情时,如果不加以约束,每个人做事的方式就会按照自己喜爱的方式进行,凌乱不堪,让后来加入者需要更多的时间,熟悉前人所做事情,然而所做的事情也是凌乱不堪的,我们为何不加以约束。

eggjs是一个nodejs框架,继承与koa框架,egg.js为企业级框架和应用而生,所奉行的宗旨约定优于配置,按照一套统一的约定进行开发。

官网地址

github个人源码: github.com/xiloudada/E…

安装

环境要求

  • nodejs环境最低要求8.x

安装脚手架

$ mkdir egg-example && cd egg-example
$ npm init egg --type=simple
$ npm i

官网也有逐步搭建过程

目录结构约束

官网目录结构约束介绍

egg-project
├── package.json
├── app.js (可选)
├── agent.js (可选)
├── app
|   ├── router.js
│   ├── controller
│   |   └── home.js
│   ├── service (可选)
│   |   └── user.js
│   ├── middleware (可选)
│   |   └── response_time.js
│   ├── schedule (可选)
│   |   └── my_task.js
│   ├── public (可选)
│   |   └── reset.css
│   ├── view (可选)
│   |   └── home.tpl
│   └── extend (可选)
│       ├── helper.js (可选)
│       ├── request.js (可选)
│       ├── response.js (可选)
│       ├── context.js (可选)
│       ├── application.js (可选)
│       └── agent.js (可选)
├── config
|   ├── plugin.js
|   ├── config.default.js
│   ├── config.prod.js
|   ├── config.test.js (可选)
|   ├── config.local.js (可选)
|   └── config.unittest.js (可选)
└── test
    ├── middleware
    |   └── response_time.test.js
    └── controller
        └── home.test.js

内置基础对象

官网内置基础对象链接

eggjs框架从koa框架继承了四个对象(Application,Context,Request,Response),框架本身也扩展了一些对象(Controller,Service,helper,Config,Looger)

Application对象

Application是一个全局对象,只会实例化一个,Application对象继承koa.Application对象,在上面可以挂载一些全局的方法和属性

简单使用

我们用业务来表述技术的使用,例如我们现在有一个记账的业务。

router

首先我们要有api接口,当我们有多个api接口时,怎么做区分? 使用router路由进行分发请求。我们在app文件下面创建router.js文件,通过从Application对象中结构出router来使用路由的功能

// router.js 
module.exports = app => {
  const { router, controller, jwt } = app;
  // 登陆接口
  router.get('/keeping/api/v1/login', controller.login.login);
  // 查询用户
  router.get('/keeping/api/v1/getUser', jwt, controller.user.selectUser);
};
// 第一个参数是访问的地址,第二个参数告诉我们匹配成功后分发到相应的controller上,

costroller

当我们分发到相应的controller上进行解析用户的输入,处理后返回相应的结果。

在app下新建controller.js文件,拿到用户的输入值,我们会把业务逻辑做一个拆分,会调用相应业务逻辑,就是我们所说的service

// controller.js
const { Controller } = require('egg');

class LoginController extends Controller {
  // 登陆api
  async login() {
    const { ctx, app } = this;
     // 拿到用户的输入值
    const query = ctx.query;
    // 调用service服务
    const loginInfo = await ctx.service.login.login(query);
   // 生成token 
    const token = app.jwt.sign({
      user: loginInfo,
    }, app.config.jwt.secret);
    const openid = loginInfo.openid;
    // 返回值
    ctx.body = {
      openid,
      token: `Bearer ${token}`,
      success: '登陆成功',
      code: 200,
    };
  }
  // 查询用户
  async selectUser() {
    const { ctx } = this;
    const query = ctx.query;
    console.log(query, '........query======');
    const user = await ctx.service.user.selectUser(query);
    if (user) {
      this.ctx.body = {
        success: true,
        message: '查询成功',
        status: 200,
        data: user,
      };
    } else {
      this.ctx.body = {
        success: false,
        message: '查询失败',
        status: 40023,
      };
    }
  }
}
module.exports = LoginController;

service

controller调用service业务逻辑,我们在app文件下新建service文件,在service文件下编写抽离出来的业务逻辑的封装,把业务逻辑抽离出来使我们的controller更加的简洁,保持业务的独立性,抽离出来的service可以被多个controller使用。

// service.js
const { Service } = require('egg');
class LoginService extends Service {
  // 登陆
  async login(data) {
    const { app, ctx } = this;
     // 这里我通过在config下面配置常量,通过引用调用,此接口是登陆接口
    const { appid, secret } = app.config.weapp;
    const result = await ctx.curl(`https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${data.code}&grant_type=authorization_code`, { dataType: 'json' });
    const aa = await ctx.service.user.selectUser(result.data);
    if (!aa) {
      await ctx.service.user.addUser({ openid: result.data.openid });
    }
    return result.data;
  }
  
  // 查询用户
  async selectUser(openid) {
    const { app } = this;
    const userTable = app.config.sqlTable.user;
    const user = await app.mysql.get(userTable, openid);
    return user;
  }

}
module.exports = LoginService;

config

当我们需要使用数据库时,我们就要使用plugin,例如我们使用mysql数据库,需要安装egg-mysql,安装后在config/plugin.js中声明:

// 配置mysql
  mysql: {
    enable: true,
    package: 'egg-mysql',
  },

然后在config/config.default.js中配置数据库连接的相关配置

// 配置mysql
  config.mysql = {
    // 单数据库信息配置
    client: {
      host: 'localhost', //主机名
      port: '3306',	//端口号
      user: 'root',	// 数据库用户名
      password: '123456', // 数据库密码
      database: 'xilou',	 //数据库表名
    },
    // 是否加载到 app 上,默认开启
    app: true,
    agent: false,
  };

后续会配置一些解决跨域的egg-cors插件,生成token的egg-jwt插件,配置如mysql一样,这样一个流程就完成了,我们使用postman进行请求下,因为数据库我已经配置好,现在进行查询用户的一个请求,数据库里面的数据是我已经插入进去的,查询用户如下

中间件

我们可以自己编写中间件,放在app/middleware文件下面,在config.default.js下面配置中间件

总结

上面阐述了eggjs的基本使用。

eggjs对开发团队进行约定,有利于团队开发,减少开发人员的学习成本,开箱即用。

  • eggjs使用路由分发请求,具体执行的动作
  • 使用controller负责解析用户的输入,处理返回相应的结果
  • 使用service处理相应的业务逻辑
  • 因为nodejs是异步,采用async来进行处理
  • 其他的无非使用插件来增强功能,例如连接数据库,要么使用中间件来增强功能,通过挂载在Application下使用

如果有哪些言辞不正之处,错误之处,欢迎指正,后续会进行更改