大纲
- 一、环境安装:
- 二、项目搭建
- 三、了解koa2的核心对象
- 四、安装Sequelize
- 五、配置Sequelize
- 六、整理项目结构
- 七、schema(数据表模型)
- 八、modules(模型)
- 九、controllers(控制器)
- 十、路由(接口)
- 十一、开启服务
- 十三、配置跨域
- 十二、测试接口
一、环境安装:
环境要求:
node -v
v8.9.3
npm -v
5.5.1
如果还没有nodejs和npm版本,就可以点击以下的网址进行下载安装:
二、项目搭建
安装好了nodejs环境后,会自动带npm管理工具,我们在电脑硬盘上面新建一个文件夹:myproject
,然后cmd黑窗口进入myproject
文件夹目录下:
第一步: 安装koa-generator
npm install koa-generator -g
第二步:使用koa-generator生成koa2项目
// 命令:koa2 "项目名称",我们可以把项目名字为:blog
koa2 blog
第三步:安装包
// 进入blog项目
cd blog
// 安装服务
npm install
第四步:启动服务
npm start
打开浏览器:http://localhost:3000/会看到“Hello Koa 2!”就是启动成功了!
三、了解koa2的核心对象
- Application 服务类
- 创建对象 => 传入中间件use(fn) => 生成一个HTTP服务器const server => http.createServer(this.callback()) => 处理响应(handleRequest)=> 返回实例
- 学习文档:Context 上下文对象
- 学习文档:Request 请求对象
- 学习文档:Response 响应对象
- 学习文档:Middlewares 中间件
四、安装Sequelize
Sequelize 是一个基于 promise 的 Node.js ORM, 目前支持 Postgres, MySQL, SQLite 和 Microsoft SQL Server. 它具有强大的事务支持, 关联关系, 读取和复制等功能.
安装命令:
npm install sequelize --save
安装mysql,mysql2
npm install mysql mysql2 --save
五、配置Sequelize
根目录下新建一个config
文件,在config
文件下新建一个db.js
文件,这个文件就是用来建立连接mysql
数据库的:
在db.js文件写入代码:
特别注意,下面代码解释:
blogs
:数据库名字- 还没有创建数据库名字:登录数据库命令:
mysql -uroot -p
- 创建blogs数据库命令:
CREATE DATABASE blogs DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
root
:本地数据库用户名password
:本地数据库密码
const Sequelize = require('sequelize');
const sequelize = new Sequelize('blogs', 'root', 'password', {
host: 'localhost',
dialect: 'mysql',
operatorsAliases: false,
dialectOptions: {
// 字符集
charset: "utf8mb4",
collate: "utf8mb4_unicode_ci",
supportBigNumbers: true,
bigNumberStrings: true
},
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
timezone: '+08:00' //东八时区
});
module.exports = {
sequelize
}
六、整理项目结构
新增三个文件夹:schema(数据表模型)
、modules(模型)
、controllers(控制器)
分别在这三个文件夹下各新建article.js
文件
├── schema
└── article.js
└── modules
└── article.js
└── controllers
└── article.js
七、schema(数据表模型)
新建一个schema
文件,这个文件夹的作用用来建立数据库的模型,可以先分析一下文章的字段:
字段 | 说明 | 必填 |
---|---|---|
id | 自增文章ID | 否 |
title | 文章标题 | 是 |
author | 文章作者 | 是 |
content | 文章内容 | 是 |
category | 文章分类 | 是 |
createdAt | 创建时间 | 否 |
updatedAt | 更新时间 | 否 |
我们来做文章接口
方法一:可以在黑窗口输入创建文章表的命令:
CREATE TABLE IF NOT EXISTS `article`(
`id` INT UNSIGNED AUTO_INCREMENT COMMENT '主键(自增长)',
`title` VARCHAR(100) NOT NULL COMMENT '文章标题',
`author` VARCHAR(40) NOT NULL COMMENT '文章作者',
`content` TEXT NOT NULL COMMENT '文章内容',
`category` VARCHAR(40) NOT NULL COMMENT '文章分类',
`createdAt` DATE COMMENT '创建时间',
`updatedAt` DATE COMMENT '更新时间',
PRIMARY KEY ( `id` )
)COMMENT = '文章表' ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
方法二:使用sequelize
管理数据库,在schema
文件夹下起个名字article.js
,这个文件是用创建文章数据表模型的,可以理解为:创建一张文章数据表:
学习文档:Sequelize Model definition - 模型定义 >
在article.js加入自动创建文章模型代码:
/**
├── schema
└── article.js
*/
const moment = require('moment');
module.exports = function (sequelize, DataTypes) {
return sequelize.define('article', {
// 文章ID
id: {
type: DataTypes.INTEGER,
primaryKey: true,
allowNull: true,
autoIncrement: true,
},
// 文章标题
title: {
type: DataTypes.STRING,
allowNull: false,
field: 'title',
},
// 文章作者
author: {
type: DataTypes.STRING,
allowNull: false,
field: 'author'
},
// 文章内容
content: {
type: DataTypes.TEXT,
allowNull: false,
field: 'content'
},
// 文章分类
category: {
type: DataTypes.STRING,
allowNull: false,
field: 'category'
},
// 创建时间
createdAt: {
type: DataTypes.DATE,
get() {
return moment(this.getDataValue('createdAt')).format('YYYY-MM-DD HH:mm:ss');
}
},
// 更新时间
updatedAt: {
type: DataTypes.DATE,
get() {
return moment(this.getDataValue('updatedAt')).format('YYYY-MM-DD HH:mm:ss');
}
}
}, {
// 如果为 true 则表的名称和 model 相同,即 user
// 为 false MySQL创建的表名称会是复数 users
// 如果指定的表名称本就是复数形式则不变
freezeTableName: true
})
}
八、modules(模型)使用
在modules
文件夹下的article.js文件,使用代码创建了一个新的文章的实例:
/**
├── modules
└── article.js
*/
// 引入刚刚在第五点建立连接mysql数据库的db.js文件
const db = require('../config/db');
// 引入Sequelize对象
const Sequelize = db.sequelize;
// 引入上一步的文章数据表模型文件
const Article = Sequelize.import('../schema/article');
// 自动创建表
Article.sync({force: false});
class ArticleModel {
/**
* 创建文章模型
* @param data
* @returns {Promise<*>}
*/
static async createArticle(data) {
return await Article.create({
title: data.title, // 文章标题
author: data.author, // 文章作者
content: data.content, // 文章内容
category: data.category, // 文章分类
})
}
/**
* 查询取文章详情数据
* @param id 文章ID
* @returns {Promise<Model>}
*/
static async getArticleDetail(id) {
return await Article.findOne({
where: {
id,
},
})
}
}
module.exports = ArticleModel
九、controllers(控制器)
Controller控制器,是MVC中的部分C,此处的控制器主要负责功能处理部分:
- 1、收集、验证请求参数并绑定到命令对象;
- 2、将命令对象交给业务对象,由业务对象处理并返回模型数据;
在controllers
文件夹下的article.js文件,加入代码:
/**
├── controllers
└── article.js
*/
const ArticleModel = require('../modules/article')
class articleController {
/**
* 创建文章
* @param ctx
* @returns {Promise.<void>}
*/
static async create(ctx) {
// 接收客服端
let req = ctx.request.body;
if (req.title // 文章标题
&& req.author // 文章作者
&& req.content // 文章内容
&& req.category // 文章分类
) {
try {
// 创建文章模型
const ret = await ArticleModel.createArticle(req);
// 把刚刚新建的文章ID查询文章详情,且返回新创建的文章信息
const data = await ArticleModel.getArticleDetail(ret.id);
ctx.response.status = 200;
ctx.body = {
code: 200,
msg: '创建文章成功',
data
}
} catch (err) {
ctx.response.status = 412;
ctx.body = {
code: 200,
msg: '创建文章失败',
data: err
}
}
} else {
ctx.response.status = 416;
ctx.body = {
code: 200,
msg: '参数不齐全',
}
}
}
/**
* 获取文章详情
* @param ctx
* @returns {Promise.<void>}
*/
static async detail(ctx) {
let id = ctx.params.id;
if (id) {
try {
// 查询文章详情模型
let data = await ArticleModel.getArticleDetail(id);
ctx.response.status = 200;
ctx.body = {
code: 200,
msg: '查询成功',
data
}
} catch (err) {
ctx.response.status = 412;
ctx.body = {
code: 412,
msg: '查询失败',
data
}
}
} else {
ctx.response.status = 416;
ctx.body = {
code: 416,
msg: '文章ID必须传'
}
}
}
}
module.exports = articleController
十、路由(接口)
路由管理,大部分是接收不同的api请求,返回数据的。例如一个 /api/v1/article的请求,得到响应,中间件处理,返回数据。
我们在根目录下的routes
文件夹的index.js
文件,加入代码,这段代码可以理解为是向外暴露的API接口,实际上是路由的访问,然后通过控制器=>模型处理(数据库查询等操作)=>返回数据
/**
├── routes
└── index.js
*/
const Router = require('koa-router')
const ArticleController = require('../controllers/article')
const router = new Router({
prefix: '/api/v1'
})
/**
* 文章接口
*/
// 创建文章接口(路由)
router.post('/article', ArticleController.create);
// 获取文章详情接口(路由)
router.get('/article/:id', ArticleController.detail);
module.exports = router
十一、开启服务
所有的文件和配置都已经弄好了,那么我们进行启动和测试:
命令进入blog
文件夹下,重启代码:
npm start
启动后会出现以下代码就说明成功了:
blog npm start
> blog@0.1.0 start /Users/bob/Documents/test/myproject/blog
> node bin/www
Ignoring invalid configuration option passed to Connection: collate. This is currently a warning, but in future versions of MySQL2, an error will be thrown if you pass an invalid configuration options to a Connection
Ignoring invalid configuration option passed to Connection: collate. This is currently a warning, but in future versions of MySQL2, an error will be thrown if you pass an invalid configuration options to a Connection
Executing (default): CREATE TABLE IF NOT EXISTS `article` (`id` INTEGER auto_increment , `title` VARCHAR(255) NOT NULL, `author` VARCHAR(255) NOT NULL, `content` TEXT NOT NULL, `category` VARCHAR(255) NOT NULL, `createdAt` DATETIME, `updatedAt` DATETIME, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `article`
十二、配置跨域
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。它的通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
npm install koa-cors --save
在根目录app.js文件下引入koa-cors
const cors = require('koa-cors');
// 使用koa-cors
app.use(cors());
配置好重新npm start
运行就可。
十三、测试接口
我们使用postman来测试接口,postman下载链接
一、创建文章接口
/article
请求方式
POST
参数
参数 | 说明 | 必填 |
---|---|---|
id | 自增文章ID | 否 |
title | 文章标题 | 是 |
author | 文章作者 | 是 |
content | 文章内容 | 是 |
category | 文章分类 | 是 |
createdAt | 创建时间 | 否 |
updatedAt | 更新时间 | 否 |
返回成功结果
{
"code": 200,
"msg": "创建文章成功",
"data": {
"createdAt": "2018-09-22 08:37:50",
"updatedAt": "2018-09-22 08:37:50",
"id": 1,
"title": "学习koa2写接口",
"author": "梁凤波",
"content": "Hello Koa2!",
"category": "nodejs"
}
}
二、查询文章接口
/article/:id
请求方式
GET
参数
参数 | 说明 | 必填 |
---|---|---|
id | 自增文章ID | 是 |
返回成功结果
{
"code": 200,
"msg": "查询成功",
"data": {
"createdAt": "2018-09-22 08:37:50",
"updatedAt": "2018-09-22 08:37:50",
"id": 1,
"title": "学习koa2写接口",
"author": "梁凤波",
"content": "Hello Koa2!",
"category": "nodejs"
}
}
总结
恭喜你,到了这步已经学会如何使用koa2写接口了,同时学会了Sequelize管理数据库,还学到了MVC的模式开发,当然这篇文章是不齐全的,本人水平有限,或有您有更好的建议和意见,请提出来告知我。
我在GitHub上面已经完善整个项目:github地址:https://github.com/liangfengbo/nodejs-koa-blog 项目技术栈为:nodejs+koa2+mysql+sequelize+jwt,使用koa2框架,sequelize管理mysql数据库,jwt做权限接口验证,实现用户、文章管理接口。
希望对你学习nodejs有帮助,谢谢!
热门评论
请问这个是restful api吗
能问一下 我跑这个项目一直返回参数不齐 求赐教
大佬,如果要修改从数据库获得的数据该怎么操作,例如给获取的对象增加一个属性。