全栈项目之后端egg起node服务

1 技术栈

egg+node
项目在线地址
http://47.100.30.67:7001
项目git地址
https://github.com/jiqingpeng/mars/tree/master/fe/egg-example

2 快速入门

egg官方推荐直接使用脚手架,只需几条简单指令,即可快速生成项目(npm >=6.1.0):

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

启动项目:

npm run dev
open http://localhost:7001

3 项目目录结构

全栈项目之后端egg起node服务

  • app/router.js 用于配置 URL 路由规则,具体参见 Router
  • app/controller/** 用于解析用户的输入,处理后返回相应的结果,具体参见Controller
  • app/model/** 框架内置对象,也可以理解为接口名称.具体参见Model
  • config/config.default.js 用于编写配置文件.具体参见配置
  • config/plugin.js 用于配置需要加载的插件,具体参见插件

4 项目详细解析

app/router.js下代码解析

'use strict';

/**
 * @param {Egg.Application} app - egg application
 */
module.exports = app => {
  const { router, controller } = app;
  router.get('/', controller.home.render);//home表接口
  router.resources('users', '/users', controller.users);//users表接口
  router.resources('info', '/info', controller.info);//users表接口
  router.resources('test', '/test', controller.test);//test表接口
  router.resources('phone', '/phone', controller.phone);//phone表接口
  
};

app/controller/info.js

// app/controller/users.js
const Controller = require ('egg').Controller;
//  转整数方法
function toInt (str) {
  if (typeof str === 'number') return str;
  if (!str) return str;
  return parseInt (str, 10) || 0;
}
//过滤对象中的空属性
function filterJson (data) {
  const json = {};
  for (item in data) {
    if (data[item]) {
      json[item] = data[item];
    }
  }
  return json;
}

class InfoController extends Controller {
    //
  async index () {
    const ctx = this.ctx;
    let {offset, limit, sex, nick} = ctx.query;
    const where = filterJson ({sex, nick});
    
    offset = toInt (offset);
    limit = toInt (limit);
    let total = null;
    let result = null;
    if (JSON.stringify (where) === '{}') {
      total = (await this.app.model.Info.findAll ({})).length;
      result = await this.app.model.Info.findAll ({
        offset,
        limit,
        include: [
          {
            model: this.app.model.Phone
          }
        ]
      });
    } else {
      total = (await this.app.model.Info.findAll ({
        where: where,
      })).length;
      result = await this.app.model.Info.findAll ({
        offset,
        limit,
        where: where,
        include: [
        {
          model: this.app.model.Phone
        }
      ]
      });
    }

    ctx.body = {
      data: result,
      total,
    };
    ctx.status = 201;
  }
  async show () {
    const ctx = this.ctx;
    const {id} = this.ctx.params;
    const Info = await ctx.model.Info.findById (id, {
      include: [
        {
          model: this.app.model.Phone,
        },
      ],
    });
    ctx.body = {
      status: true,
      res: Info,
    };
    ctx.status = 201;
  }
  async create () {
    const ctx = this.ctx;
    const {phone_id, nick, sex, head_url} = ctx.request.body;
    const info = await ctx.model.Info.create ({phone_id, nick, sex, head_url});
    ctx.status = 201;
    ctx.body = {
      state: true,
      res: info,
    };
  }
  async update () {
    const ctx = this.ctx;
    const id = toInt (ctx.params.id);
    const result = await ctx.model.Info.findById (id);
    const {nick, sex, head_url} = ctx.request.body;
    
    await result.update ({nick, sex, head_url});
    ctx.status = 201;
    ctx.body = {
      state: true,
      res: result,
    };
  }

  async destroy (id) {
    const ctx = this.ctx;
    await ctx.delete (id);
    ctx.status = 200;
  }
}

module.exports = InfoController;
  • findByID/findAll等方法以及参数limt,offset,where等查询规则的使用是基于 promise 的 Node.js ORM的一个库 Sequelize具体参见 Sequelize Docs 中文文档版 。
  • index/update/show/create/destroy restful风格定义接口规则如下图

全栈项目之后端egg起node服务
详情参见https://eggjs.org/zh-cn/basics/router.html

5 接口文档

phone
请求url:

请求方式:

  • GET

参数:

参数名是否必填类型说明
phonestring手机号

注意 http get请求参数要放在URL中,除非做特殊处理
请求url:

请求方式:

  • POST

参数:

参数名是否必填类型说明
phonestring手机号
pwdstring密码

请求url:

请求方式:

  • PUT

参数:

参数名是否必填类型说明
pwdstring密码

请求url:

请求方式:

  • DELETE

参数:

参数名是否必填类型说明
idint账号id