eggJS 入门分享

5 篇文章 0 订阅
5 篇文章 0 订阅

快速初始化

我们推荐直接使用脚手架,只需几条简单指令,即可快速生成项目:


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

启动项目:


$ npm run dev
$ open localhost:7001

启动后的界面

image.png

注意:这里默认地址是7001,如果修改,可以在config配置文件里面做如下修改:

// 自定义端口
config.cluster = {
  listen: {
  	port: 7010
  }
};

框架目录结构

  • egg.js是约定优于配置的
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

如上,由框架约定的目录:

  • app/router.js 用于配置 URL 路由规则,具体参见 Router
  • app/controller/** 用于解析用户的输入,处理后返回相应的结果,具体参见 Controller
  • app/service/** 用于编写业务逻辑层,可选,建议使用,具体参见 Service
  • app/middleware/** 用于编写中间件,可选,具体参见 Middleware
  • app/public/** 用于放置静态资源,可选,具体参见内置插件 egg-static
  • app/extend/** 用于框架的扩展,可选,具体参见框架扩展
  • config/config.{env}.js 用于编写配置文件,具体参见配置
  • config/plugin.js 用于配置需要加载的插件,具体参见插件
  • test/** 用于单元测试,具体参见单元测试
  • app.jsagent.js 用于自定义启动时的初始化工作,可选,具体参见启动自定义。关于agent.js的作用参见Agent机制

由内置插件约定的目录:

  • app/public/** 用于放置静态资源,可选,具体参见内置插件 egg-static
  • app/schedule/** 用于定时任务,可选,具体参见定时任务

怎么写一个接口?

后台接口避免不了和数据库打交道,下面例子咱们使用MySQL,ORM使用sequelize
首先安装MySQL数据库(安装教程),以及navicat界面管理工具,这样就可以验证自己操作数据库是否成功。

egg中使用MySQL

安装对应的插件 egg-mysql


$ npm i --save egg-mysql

开启插件:


// config/plugin.js
exports.mysql = {
enable: true,
package: ‘egg-mysql’,
};

config/config.${env}.js 配置各个环境的数据库连接信息。更详细教程参考官方文档


安装并配置 egg-sequelize 插件

(它会辅助我们将定义好的 Model 对象加载到 app 和 ctx 上)和 mysql2 模块

  • 安装


npm install --save egg-sequelize mysql2

  • config/plugin.js 中引入 egg-sequelize 插件


exports.sequelize = {
enable: true,
package: ‘egg-sequelize’,
};

这里有个坑,egg项目初始化plugin.js导出使用的module.exports,而教程里又是 exports导出,这两者不能并存的,有多坑?你自己体验吧!如果使用module.exports就要以key: value的形式配置插件!不懂这俩区别的人就容易入坑!!!嗯~我就入了,所以推荐一篇文章https://www.imooc.com/article/34483

image.png

  • config/config.default.js 中编写 sequelize 配置
​
config.sequelize = {

    dialect: 'mysql',

    host: '127.0.0.1',

    port: 3306,

    database: 'dev2',

    username: 'root',

    password: '',

    timezone: "+08:00",

};

​

更详细教程参考官方文档


1. Router

Router 主要用来描述请求 URL 和具体承担执行动作的 Controller 的对应关系, 框架约定了 app/router.js 文件用于统一所有路由规则。通过统一的配置,我们可以避免路由规则逻辑散落在多个地方,从而出现未知的冲突,集中在一起我们可以更方便的来查看全局的路由规则。

下面我们添加一个注册接口,在app/router.js添加

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;

  //注册
  app.post("/example/register", app.controller.userControl.register);	

  router.get('/*', controller.home.index);
};

更详细教程参考官方文档


2. Controller

一切准备就绪后,开始我们的第一个Controller。我们下载的simple类型的example目录结构中是有controller这样一个目录。注意我在文章开头提到过,egg.js是约定优于配置的,这些目录是什么意思都可以在(官方教程的目录结构中看到)这个controller目录结构就是指明这个目录就是一个Controller,所有跟Controller有关的东西都放在这个目录下面。

下面我们自定义一个controller看看效果,在controller文件夹下新建一个userControl.js文件

'use strict';

const Controller = require('egg').Controller;
class userControl extends Controller {
    async register() {
        const { ctx } = this;
        const params = ctx.request.body;  // 获取请求参数

        // 校验规则
        const rule = {
            username: { type: 'string' },
            password: { type: 'string' },
        };

        try {
            ctx.validate(rule, params);  // 参数校验

            const data = await ctx.service.userServer.register(params);  // 把业务逻辑交给service处理

            ctx.body = JSON.stringify(data);  // 成功返回前端
        } catch (err) {
            ctx.body = JSON.stringify(err);  // 异常返回前端
            ctx.logger.info("userControl.register-error: ", JSON.stringify(err));  // 异常打印日志
        }
    }
}

module.exports = userControl;

参数校验egg自带了egg-validate,用的不是很舒服,我个人推荐使用egg-joi,使用方式我的博客有写哦,
一波小广告=>eggJS egg-joi优雅的参数校验

更详细教程参考官方文档


3. Service

Service是业务逻辑层在我们自己下载的example中是没有这么一项的,但是在官方教程的目录结构中是有的,只是被标注了可选。首先我们需要在app下创建一个service的文件夹用来存放service文件(注意约定大于配置),再在service文件夹下新建一个userServer.js文件用来编写service代码

下面我们自定义一个service看看效果,先建一个service文件夹,在service文件夹下新建一个userServer.js文件

const Service = require('egg').Service;

class userServer extends Service {

    async register(params) {
        const ctx = this.ctx;
        try {
            // 我这里没有做复杂的业务逻辑,注册直接存库,所以就调用下model里的insertUserInfo方法
            const results = await ctx.model.UserModel.insertUserInfo(params);
            return results;
        } catch (err) {
            ctx.body = JSON.stringify(err);
        }
    }

}

module.exports = userServer;

更详细教程参考官方文档


4. Model

egg-sequelize会自动将sequelize实例挂载到app.model上面,然后静态方法和属性则会直接被绑定到app上,通过app.Sequelize进行获取。
model层作为MVC的最底层,需要注意到数据模型的pure,model文件也应该是纯净的,这个文件里面应该是和数据库中的表一一对应,一个model文件对应一个DB中的表,这个文件中不应该包含任何和逻辑相关的代码,应该完全是数据模型的定义。

下面我们自定义一个model看看效果,先建一个model文件夹,再在model文件夹下新建一个UserModel.js文件

'use strict';

module.exports = app => {
    const Sequelize = app.Sequelize;

    const UserModel = app.model.define('user', {
        id: {
            type: Sequelize.INTEGER,
            primaryKey: true,
            autoIncrement: true,
        },
        username: {
            type: Sequelize.STRING,
        },
        password: {
            type: Sequelize.STRING,
        },
    }, {
            tableName: 'user',
            timestamps: true,
            underscoredAll: true
        });
	/**
	 * 插入数据
	 */
    UserModel.insertUserInfo = (params) => {
        return new Promise((resolve, reject) => {
            UserModel.create({
                username: params.username,
                password: params.password,
            }).then(results => {
                // console.log("UserModel.updateUserInfo-results===", results);
                if (results && results.dataValues) {
                    resolve(results.dataValues);
                } else {
                    reject(false);
                }
            }).catch((err) => {
                console.log('UserModel.updateUserInfo-err===', err);
                reject(err);
            });
        });
    };

    return UserModel;
};

sequelize使用原始查询方法写SQL语句使用Sequlize提供的工具函数sequelize.query来实现。
上面的插入方法用SQL写如下:

UserModel.insertUserInfo = (params) => {
		return new Promise((resolve, reject) => {
			let sql = `INSERT INTO user (username, password,created_at, updated_at) VALUES ('${params.username}', '${params.password}', now(), now())`;

			app.model.query(sql).spread((results, metadata) => {
				// console.log("UserModel.updateUserInfo-results===", results);
                if (results && results.dataValues) {
                    resolve(results.dataValues);
                } else {
                    reject(false);
                }
			}).catch(err => {
				console.log('UserModel.insertUserInfo-err======', err);
				reject(err);
			});
		});
	};

sequelize的确很便捷,提供的方法也比较多,我这里就拿一个举例,其他的大家可以去网上找文章,很多的。
如果要使用连接MongoDB的话可以参考我的一篇博客eggJS 连接和使用Mongodb


咱们调用一下,看下接口返回的结果,这里推荐一个工具postman
image.png


应用部署

  1. 在该文件下打包,生成tgz文件:tar -zcvf …/FileName.tgz

  2. 环境部署(建议下载Xshell客户端,当然别的工具都可以,根据个人喜好~~~)

    a.进入要部署的服务器对应文件夹下,cd 等等;
    b.//创建文件 mkdir 文件名称;
    c.打开压缩包: rz -be;
    d.解包:tar zxvf FileName.tar;
    e.移除压缩包: rm -rf FileName.tar

  3. 然后就可以启动啦:npm start即可。

更详细教程参考官方文档


本节demo:https://gitee.com/netbuggang/egg-example

参考文献:
https://eggjs.org/zh-cn/tutorials/index.html
https://www.jianshu.com/p/6b04330ee4a1
https://blog.csdn.net/qq_35954591/article/details/78803859

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值