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
koa2+mysql实现RESTful API相关推荐
- 最好用的koa2+mysql的RESTful API脚手架,mvc架构,支持node调试,pm2部署。
#基于webpack构建的 Koa2 restful API 服务器脚手架 这是一个基于 Koa2 的轻量级 RESTful API Server 脚手架,支持 ES6, 支持使用TypeScript ...
- koa2 mysql sequelize_使用nodejs-koa2-mysql-sequelize-jwt 实现项目api接口
nodejs-koa2-mysql-sequelize-jwt 技术栈:nodejs, koa2, mysql, sequelize, jwt 项目数据层和操作层分明 使用koa2框架中间件,参数处理 ...
- 分享Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站
这是个什么的项目? 使用 Node.js + Koa2 + MySQL + Vue.js 实战开发一套完整个人博客项目网站. 博客线上地址:www.boblog.com Github地址:https: ...
- 用python写通用restful api service(一)
一直在用node.js做后端,要逐步涉猎大数据范围,注定绕不过python,因此决定把一些成熟的东西用python来重写,一是开拓思路.通过比较来深入学习python:二是有目标,有动力,希望能持之以 ...
- 用 Flask 来写个轻博客 (36) — 使用 Flask-RESTful 来构建 RESTful API 之五
Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 PUT 请求 DELETE 请求 测试 对一条已经存在的 posts ...
- 用 Flask 来写个轻博客 (35) — 使用 Flask-RESTful 来构建 RESTful API 之四
Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 POST 请求 身份认证 测试 前文列表 用 Flask 来写个轻博客 ...
- 用 Flask 来写个轻博客 (34) — 使用 Flask-RESTful 来构建 RESTful API 之三
Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 应用请求中的参数实现 API 分页 测试 前文列表 用 Flask 来 ...
- 用 Flask 来写个轻博客 (33) — 使用 Flask-RESTful 来构建 RESTful API 之二
Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 构建 RESTful Flask API 定义资源路由 格式 ...
- 用 Flask 来写个轻博客 (32) — 使用 Flask-RESTful 来构建 RESTful API 之一
Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 RESTful API REST 原则 无状态原则 面向资源 ...
- 人人都是 API 设计者:我对 RESTful API、GraphQL、RPC API 的思考
有一段时间没怎么写文章了,今天提笔写一篇自己对 API 设计的思考.首先,为什么写这个话题呢?其一,我阅读了<阿里研究员谷朴:API 设计最佳实践的思考>一文后受益良多,前两天并转载了这篇 ...
最新文章
- 深拷贝与浅拷贝~动态内存释放有关
- java.util类,GitHub - yutaolian/JavaUtils: 总结的一些Java常用的util类
- 为什么SAP UI5框架在应用整个生命周期只调用onBeforeRendering一次
- Java的多态形式中,如何访问成员变量和调用成员方法
- 游戏教玩家学java,技术|帮你学习Java语言的游戏
- IDEA 2020 配置 Maven 创建 Spring Boot 项目
- web系统服务器登录不上去,宝塔面板严重错误登录不上怎么办
- 支持扫描的单usb口打印服务器,USB设备服务器 轻松实现扫描仪网络共享
- doc创建计算机用户,问什么我电脑一直创建这些文件夹?$RECYCLE.BIN qqpcmgr_docpro System Volume Information...
- edk2中的全局变量gST和gBS
- 消极和积极的道德--给亲爱的安德烈
- gd32f103 调试 ad7606
- JPush推送 之 RegistrationID 精确对点推送
- data单复数一样吗_data的复数形式是datas还是data?rt
- centos-基本命令
- Unity开发HTC vive 五、拾取和触碰
- bcma错误linux,linux – Broadcom Corporation BCM4313 WLAN无法在已...
- matlab 总谐波失真,分析谐波失真
- MATLAB Simulink Example
- MathWorks 中国
- 51单片机定时器(T0/T1)的使用与配置流程
- 【CSS3 属性】CSS 3 transform:scale 与 transform:translate 作用在同一div元素,导致元素位置偏离