koa2+mysql实现RESTful API

先贴上项目地址:https://gitee.com/wuchunling/koa2-mysql

再上postman测试效果图

 

看看最终的项目结构如下

-koa2+mysql

 - model 数据库表设计

 - routers 路由

 - static 静态资源  // 现在暂时用不到

 - utils 封装工具函数

 - app.js 启动文件

 - config.js 配置文件

 

 

第一步:在项目根目录下安装 koa koa-bodyparser等依赖模块

最终依赖文件package.json如下

{
  "name": "koa2",
  "version": "1.0.0",
  "description": "koa2 实现 restful api",
  "repository": {
    "type": "git",
    "url": ""
  },
  "author": "wuchunling",
  "license": "MIT",
  "dependencies": {
    "glob": "^7.1.3",
    "jsonwebtoken": "^8.4.0",
    "koa": "^2.6.2",
    "koa-body": "^4.0.4",
    "koa-bodyparser": "^4.2.1",
    "koa-cors": "0.0.16",
    "koa-jwt": "^3.5.1",
    "koa-router": "^7.4.0",
    "koa-session": "^5.10.0",
    "koa-static": "^5.0.0",
    "mysql": "^2.16.0"
  }
}

 

最终app.js如下

//启动文件(入口文件)
const Koa = require('koa')
const bodyParser  = require('koa-bodyparser')   //上下文解析
const static = require('koa-static')    //静态资源服务
const path = require('path')
const cors = require('koa-cors')       //跨域访问组件
const registerRouter = require('./routers/index')
const app = new Koa()
require('./model/index')
// 配置静态资源文件
const  staticPath = './static'
app.use(static(
    path.join( __dirname, staticPath)
))
app.use(cors()) // 允许跨域访问
app.use(bodyParser()) // body解析
app.use(registerRouter())
app.listen(3000)
console.log("启动成功")

 

 

第二步: 配置文件,配置数据库的基本信息。我用的是mysql数据库,默认端口号是3306。

config.js如下

//配置文件:数据库配置/日志配置/服务配置/....

const config = {
  port:3000,  // 项目启动端口号
  database:{   // 数据库配置信息
    host:'localhost',
    port:'3306',
    user:'用户名',
    password:'密码',
    database:'数据库名'
  }
}

module.exports = config;

 

 

第三,安装nodejs的mysql模块,建立mysql连接,封装通用的sql请求函数query

3.1 利用第二步的数据库配置信息,建立连接池 mysql.createPool(config)

const config = require('../config').database
const mysql = require('mysql')
const pool = mysql.createPool(config)

3.2 封装一个通用的sql查询语句函数

const query = function(sql,succCb,errCb){
  pool.getConnection(function(err,conn){
    if (err) {
      let data = {
        code:500,
        message:"请求失败",
        data:err
      };
      errCb(data);
    }else {
      conn.query(sql,function(err,result){
        if (err) {
          let data = {
            code:500,
            message:"请求失败",
            data:err
          };
          errCb(data);
        }else {
          succCb(result);
          conn.release();
        }
      })
    }
  })
}
module.exports = query;

query(sql,succCb,errCb)的三个参数,

第一个sql,传递的是sql语句,例如 'select * from apples'

第二参数succCb,是数据库查询成功的回调函数

第三个参数errCb,是数据库查询失败的回调函数

 

第四步,在第三步query的封装基础上可以进一步封装,代码有点长,戳链接看

https://gitee.com/wuchunling/koa2-mysql/blob/master/utils/sql.js

这一层封装,主要利用Promise对象进行二次封装,方便后续使用async/await进行调用

 

 

 

前面都是工具的准备,接下来可以磨刀霍霍向猪羊了。

接下来进入重头戏router和model的编写。(因为有了前面的工具函数的封装,这两步编写将十分的简单)

 

第五步:model数据模型。对应我们数据库表的结构的编写。以user举例

model.js

const query = require('../utils/query');

const tables = {
  users:`create table if not exists users(
   id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
   name VARCHAR(20) NOT NULL,
   phone CHAR(11) NOT NULL,
   password VARCHAR(20) NOT NULL,
   avator VARCHAR(255) DEFAULT 'default.jpg',
   credit INT NOT NULL DEFAULT 0 ,
   useCredit INT NOT NULL DEFAULT 0 ,
   cash INT NOT NULL DEFAULT 0 ,
   isReal TINYINT NOT NULL DEFAULT 0
  );`,//用户表
  // ....可以继续扩充其他表结构
}

const createTable = function(tb){
  query(tb,function(res){
    // console.log('建表成功');
    return true;
  },function(err){
    console.log('建表失败',err);
    return false;
  })
}

for (let key in tables) {
  if (tables.hasOwnProperty(key)) {
    createTable(tables[key]);
  }
}

 

第六步:路由的编写

在前面我封装了Sql对象,里面有一些常用的查询方法,①根据表名获取全部数据queryAll,②根据表名和id查询具体某一条数据query③insert④insertRows等等基本的CRUD操作。

const router = require('koa-router')();   //路由
const Sql = require('../utils/sql');
const tbName = 'apples';
 router
  .get('/api/apples',async(ctx,next) => {
    let data = await Sql.queryAll(tbName,ctx.request.query);
    ctx.body = data;
  })
  .get('/api/apples/:id',async(ctx,next) => {
    let data = await Sql.query(tbName,ctx.params.id);
    ctx.body = data;
  })

  .post('/api/apples',async(ctx,next) => {
    let data = await Sql.insert(tbName,ctx.request.body);
    ctx.body = data;
  })
  .post('/api/apples/rows',async(ctx,next) => {
    let data = await Sql.insertRows(tbName,ctx.request.body);
    ctx.body = data;
  })

  .put('/api/apples/:id',async(ctx,next) => {
    let data = await Sql.update(tbName,ctx.params.id,ctx.request.body);
    ctx.body = data;
  })
  .put('/api/apples',async(ctx,next) => {
    console.log(ctx.request.body);
    let data = await Sql.updateRows(tbName,ctx.request.body);
    ctx.body = data;
  })

  .del('/api/apples/:id',async(ctx,next) => {
    let data = await Sql.delete(tbName,ctx.params.id);
    ctx.body = data;
  })
  .del('/api/apples',async(ctx,next) => {
    let data = await Sql.deleteRows(tbName,ctx.request.body);
    ctx.body = data;
  })
module.exports = router;

 

最后一步,别忘了注册路由

app.use(appleRouter);

但是我们路由文件很多,不可能一个一个import,多累啊,万一漏了那个呢?麻烦。

所以还是利用glob和koa-compose来聚合一下我们routers文件夹下面的的所有路由文件

 

// routers/index.js
const compose = require('koa-compose')
const glob = require('glob')
const { resolve } = require('path')

registerRouter = () => {
    let routers = [];
    glob.sync(resolve(__dirname, './', '**/*.js'))
        .filter(value => (value.indexOf('index.js') === -1))
        .map(router => {
            routers.push(require(router).routes())
            routers.push(require(router).allowedMethods())
        })
    return compose(routers)
}

module.exports = registerRouter

最后在主启动文件app.js

const registerRouter = require('./routers/index');

app.use(registerRouter());

即可将全部的路由注册。

 

 

 

node app.js我们的应用就跑起来了。可以调用我们编写好的restful api了。这样就实现了开头的gif图展示的效果了。

 

系不系 very simple啊

 

 

另外,

用于登录注册等需要识别用户身份的,我们用token(jsonwebtoken)

token的加密解密也做一个基本的封装,具体调用方法戳链接

https://blog.csdn.net/qq_30604453/article/details/85060077

const jwt = require('jsonwebtoken');
const Token = {
  encrypt:function(data,time){ //data加密数据,time过期时间
    return jwt.sign(data, 'token', {expiresIn:time})
  },
  decrypt:function(token){
    try {
      let data = jwt.verify(token, 'token');
      return {
        token:true,
        id:data.id
      };
    } catch (e) {
      return {
        token:false,
        data:e
      } 
    }
  }
}
module.exports = Token

 

 

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值