Eggjs 搭配 Swagger 和 Sequelize 编写接口文档 上手教程

前言

        Eggjs 是阿里巴巴团队开发的,一个基于 Koajs 的框架,相当于二次封装,和 Koajs 一样,它的性能也是比较高的,但是相比较 Koajs ,并没有那么高的自由度,相比于 Koajs 来说,Eggjs 这种带有规范性的开发更适合在企业中使用。

        Swagger 是RESTFUL接口的文档在线自动生成工具。
        Sequelize 是基于Nodejs功能强大的异步ORM框架。 同时支持PostgreSQL, MySQL, SQLite and MSSQL多种数据库

项目搭建

        Eggjs 分为两种搭建方式,快速搭建逐步搭建,为了让大家更好的了解 Egg.js,这里使用逐步搭建

项目目录
egg_folder
    ├── app
    │   ├── contract
    │   │   └── format.js
    │   ├── controller
    │   │   └── home.js
    │   ├── extend
    │   │   └── helper.js
    │   ├── service
    │   │   └── home.js
    │   └── router.js
    ├── config
    │   └── config.default.js
    │   └── plugin.js
    ├── node_modules
    └── package.json
初始化项目

        在项目文件夹( egg_folder )里首先 cmd 运行npm init来获取package.json文件,再运行npm install egg --savenpm install egg-bin --save-dev安装 Eggjs 依赖包和 本地开发工具( 没安装 npm 的自行安装 )。

        之后在package.json的 script 里面配置运行dev命令

/* egg_folder/package.json */
"scripts": {
    "dev": "egg-bin dev --port 7007",
    "dbinit": "egg-sequelize-auto -o ./app/model -h localhost -p 3306 -d library -u root -x haosql",
    "test": "echo \"Error: no test specified\" && exit 1"
},

        然后在 cmd 运行npm run dev,如果顺利就会如下图所示。

npm run dev's result.

        如果直接在浏览器打开,就会出现这样的界面,500 那是因为什么都没做,但至少项目已经成功的启动了。


Eggjs 搭配 Swagger 和 Sequelize 编写接口文档 上手教程_第1张图片
http://localhost:7007/
配置 Cookie 秘钥

        首先配置 Cookie 秘钥,详见官网。

/* egg_folder/config/config.default.js */
'use strict';

exports.keys = 'egg_folder';

keys 配置成一个字符串,可以按照逗号分隔配置多个 key

配置路由

        接下来开始配置路由,在 router.js 里开始定义路由:

/* egg_folder/app/router.js */
'use strict';

module.exports = function (app) {
    app.router.get('/', 'home.index'); // 第一个参数为 url 路径,第二个参数的说直接点就是 controller 下的"文件名.方法"( 例如:'home.index'就会去找 egg_folder/app/controller 下的 home.js,然后再这个 js 里面找到 index 方法 )。
}

        其中 app 是 Eggjs 的全局应用对象,具体详见官网

Application 是全局应用对象,在一个应用中,只会实例化一个,它继承自 Koa.Application,在它上面我们可以挂载一些全局的方法和对象。我们可以轻松的在插件或者应用中扩展 Application 对象。

定义 Controller

        设置完后就在 home.js 里面定义 index 方法:

/* egg_folder/app/controller/home.js */
'use strict';

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

// 通过定义 Controller 类的方式来编写代码,所有的 Controller 文件都必须放在 app/controller 目录下。
class HomeController extends Controller {
    async index () {
        this.ctx.body = 'Hello World!'; // 设置响应内容。
    }
}

module.exports = HomeController;

        重新运行 npm run dev ,页面就不会报错了。

Eggjs 搭配 Swagger 和 Sequelize 编写接口文档 上手教程_第2张图片
Hello World!

安装和配置 Swagger 和 Sequelize

        现在已经完成页面的显示了,接下来就可以搭配 Swagger 和Sequelize 开始写接口了。

        首先还是安装依赖包。

npm install egg-sequelize --save
npm install egg-sequelize-auto --save-dev // 对照数据库自动生成相应的 models 减少了对数据库进行增删改查时的 sql 语句的编写。
npm install egg-swagger-doc --save

        因为是插件,所以要在 config.default.js 和 plugin.js 里配置插件信息。

/* egg_folder/config/config.default.js */
'use strict';

exports.keys = "egg_folder";

// egg-swagger-doc 配置信息。
exports.swaggerdoc = {
    dirScanner: './app/controller', // 配置自动扫描的控制器路径。
    // 接口文档的标题,描述或其它。
    apiInfo: {
        title: 'NAPI',  // 接口文档的标题。
        description: 'swagger-ui for NAPI document.',   // 接口文档描述。
        version: '1.0.0',   // 接口文档版本。
    },
    schemes: ['http', 'https'], // 配置支持的协议。
    consumes: ['application/json'], // 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html。
    produces: ['application/json'], // 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回。
    securityDefinitions: {  // 配置接口安全授权方式。
        // apikey: {
        //   type: 'apiKey',
        //   name: 'clientkey',
        //   in: 'header',
        // },
        // oauth2: {
        //   type: 'oauth2',
        //   tokenUrl: 'http://petstore.swagger.io/oauth/dialog',
        //   flow: 'password',
        //   scopes: {
        //     'write:access_token': 'write access_token',
        //     'read:access_token': 'read access_token',
        //   },
        // },
    },
    enableSecurity: false,  // 是否启用授权,默认 false(不启用)。
    // enableValidate: true,    // 是否启用参数校验,默认 true(启用)。
    routerMap: true,    // 是否启用自动生成路由,默认 true (启用)。
    enable: true,   // 默认 true (启用)。
};

// 数据库配置信息。
exports.sequelize = {
    dialect: 'mysql',   // 数据库类型,支持 mysql,sqlite,mssql,pgsql,oracle。
    host: "localhost",  // 数据库服务器地址。
    port: 3344, // 数据库连接端口号。
    database: "database", // 数据库名称。
    username: "username",   // 数据库登录用户名。
    password: "password",   // 数据库登录密码。
    define: {
        freezeTableName: true, // Model 对应的表名将与model名相同。
        timestamps: false // 默认情况下,Sequelize会将createdAt和updatedAt的属性添加到模型中,以便您可以知道数据库条目何时进入数据库以及何时被更新( 确实是太方便了,然而我们一般用不到 ....)。
    }
};
/* egg_folder/config/plugin.js */
'use strict';

// 配置 egg-swagger-doc 插件信息。
exports.swaggerdoc = {
    enable: true,   // 是否启用。
    package: 'egg-swagger-doc', // 指定包名称。
};

// 配置 egg-sequelize 插件信息。
exports.sequelize = {
    enable: true, // 是否启用。
    package: 'egg-sequelize', // 指定包名称。
};

        之后在 package.json 的 script 里面添加把数据库生成 models 的命令( -o 表示生成 models 的路径,-h 表示主机,-p 表示端口,-d 表示数据库, -u 表示用户名,-x 表示密码。别问为什么这么命名.... )。

"scripts": {
    "dev": "egg-bin dev --port 7007",
    "dbload": "egg-sequelize-auto -o ./app/model -h localhost -p 3344 -d database -u username -x password",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

        然后直接运行 npm run dbload ,就会生成相对应的 model 了( 如果配置都没错的话.... )。

Eggjs 搭配 Swagger 和 Sequelize 编写接口文档 上手教程_第3张图片
npm run dbload's result.
编写 Service 和 Controller

        配置完毕,就可以开始写 Service( 业务层 ) 了。

/* egg_folder/app/service/book.js */
'use strict';

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

// 通过定义 Service 类的方式来编写代码,所有的 Service 文件都必须放在 app/service 目录下。
class BookService extends Service {
    constructor(ctx) {
        super(ctx); // 调用父对象上的函数。
        this.tableName = 'Book'; // 数据库表名。
        this.database = this.ctx.model[this.tableName]; // 获取 model 下的表( model 相当于数据库的表 )。
    }

    /**
     * 根据Id获取表信息。
     * @param {*} id 
     */
    async selectById (id) {
        const result = await this.database.findByPk(id); // sequelize 内置查询方法。
        return result;
    }
}

module.exports = BookService;

        然后开始写 Controller ( 控制器 )调用 Service( 业务层 ) 进行业务处理。

/* egg_folder/app/controller/book.js */
'use strict';

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

/**
* @controller BookController( 注释必写,swagger-doc是根据这段注释来生成接口的 )。
*/
class BookController extends Controller {
    /**  ( 注释必写,swagger-doc是根据这段注释来生成接口详细信息的 )。
    * @summary 根据ID查询信息。
    * @description 根据ID查询信息。
    * @router get /version01/controllers/selectById ( get 表示设置请求为 get 请求,最后的 selectById 对应下面的 selectById 方法 )。
    * @request query integer Id 需要去查新的ID。( get 对应 query 请求,请求值设定为 integer 纯数字类型,ID 为请求的字段,注意大小写,和下面的方法要一一对应,不然会报错 )。
    * @response 200 JsonBody 返回结果。( 对应 contract 里面的验证属性,下面会提到 。)
    */
    async selectById () {
        const ctx = this.ctx; // 当前请求的上下文 Context 对象的实例,通过它我们可以拿到框架封装好的处理当前请求的各种便捷属性和方法。
        const service = this.service; // 应用定义的 Service,通过它我们可以访问到其他业务层,等价于 this.ctx.service 。

        const param = ctx.query; // 获取请求参数。
        const result = await service.book.selectById(param.Id); // 查找 service/book.js 下的 selectById 方法。

        this.JsonBody(result);
    }

    /*
     * 对返回的数据结果进行封装。
     */
    JsonBody (data) {
        this.ctx.body = {
            result: data,
        };
    }
}

module.exports = BookController;

上面 Controller 的注释必须要按照规范填写,不然 swagger-doc 会无法生成对应的结果,甚至报错。具体格式可以去 swagger-doc 的官网或 github 查看。

编写 Contract

        Contract 相当于验证,在接收请求和返回数据的时候对数据进行格式约束。

/* egg_folder/app/contract/format.js */
module.exports = {
    JsonBody: { // 这个名字对应上面 Controller 注释的@response 的 JsonBody。
        result: { type: 'string' }, // 服务器返回的数据。
    },
};

        最后,cmd 运行 npm run dev,然后再浏览器上输入 URL( 由于用了 swagger-doc,所以要在后面加上 /swagger-ui.html 来访问 swagger-ui,嫌麻烦的也可以自己改 )。

Eggjs 搭配 Swagger 和 Sequelize 编写接口文档 上手教程_第4张图片
http://127.0.0.1:7007/swagger-ui.html#/

Eggjs 搭配 Swagger 和 Sequelize 编写接口文档 上手教程_第5张图片
finally result.

至此 大功告成,利用这些已经可以完成对数据的增删查改了,这是我写的一个小 DEMO,已经成功完成增删查改。

总结步骤:
  • 初始化项目;
  • 建立项目目录;
  • 配置 Cookie 秘钥;
  • 配置路由;
  • 安装和配置 Swagger 和 Sequelize;
  • 根据数据库生成对应的 Model;
  • 编写 Service( 业务层 ) 和 Controller( 控制器 );
  • 编写 Contract 对格式进行约束;
  • 最后npm run dev运行项目,结束

你可能感兴趣的:(Eggjs 搭配 Swagger 和 Sequelize 编写接口文档 上手教程)