koa2 官網(wǎng)
什么是koa?
Koa 是一個(gè)新的 web 框架,由 Express 幕后的原班人馬打造, 致力于成為 web 應(yīng)用和 API 開發(fā)領(lǐng)域中的一個(gè)更小、更富有表現(xiàn)力、更健壯的基石。 通過利用 async 函數(shù),Koa 幫你丟棄回調(diào)函數(shù),并有力地增強(qiáng)錯(cuò)誤處理。 Koa 并沒有捆綁任何中間件, 而是提供了一套優(yōu)雅的方法,幫助您快速而愉快地編寫服務(wù)端應(yīng)用程序。
初始化koa項(xiàng)目
npm init
安裝koa
npm i koa
新建一個(gè)app.js
// 導(dǎo)入koa
const Koa = require('koa')
// 創(chuàng)建一個(gè)koa對象
const app = new Koa()
//監(jiān)聽端口
const port = 3000
app.listen(port);
console.log(`啟動(dòng)成功,服務(wù)端口為:${port}`)
運(yùn)行app.js
node app.js
// console.log(`啟動(dòng)成功,服務(wù)端口為:${port}`)

添加啟動(dòng)腳本命令
//package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev":"node app.js"
}
可以運(yùn)行 npm run dev啟動(dòng)我們的服務(wù)。
使用 www 啟動(dòng)服務(wù)
在根目錄建立 bin文件夾,然后新建 www文件
// bin/www
var app = require('../app');
var http = require('http');
var server = http.createServer(app);
//服務(wù)監(jiān)聽端口
server.listen('3001');
配置www啟動(dòng)腳本
//package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev":"node bin/www"
}
然后 npm run dev就能啟動(dòng)了。
加點(diǎn)服務(wù)的返回內(nèi)容
// 導(dǎo)入koa
const Koa = require('koa')
// 創(chuàng)建一個(gè)koa對象
const app = new Koa()
//返回的內(nèi)容
app.use(async ctx => {
ctx.body = 'Hello World';
});
//監(jiān)聽端口
const port = 3000
app.listen(port);
console.log(`啟動(dòng)成功,服務(wù)端口為:${port}`)

安裝中間件 koa-bodyparser
這個(gè)中間件可以將post請求的參數(shù)轉(zhuǎn)為json格式返回;
npm install --save koa-bodyparser
bodyparser 使用
// 導(dǎo)入koa
const Koa = require('koa')
const bodyParser = require('koa-bodyparser');
// 創(chuàng)建一個(gè)koa對象
const app = new Koa()
app.use(bodyParser());
// request.method可以獲取請求方法。
// get,post或者其他類型(request對象被封在ctx內(nèi),所以也可以ctx.method獲取)
app.use(async (ctx) => {
if (ctx.url === '/' && ctx.method === 'POST') {
ctx.body = ctx.request.body
} else {
// 其他請求顯示404
ctx.body = '<h1>404!</h1>'
}
})
//監(jiān)聽端口
const port = 3000
app.listen(port);
console.log(`啟動(dòng)成功,服務(wù)端口為:${port}`)
開始寫接口之前,我們安裝一下路由 Koa-router
Koa-router是 koa 的一個(gè)路由中間件,它可以將請求的URL和方法(如:GET 、 POST 、 PUT 、 DELETE 等) 匹配到對應(yīng)的響應(yīng)程序或頁面。
npm install koa-router --save
使用koa-router
const Router = require('koa-router'); // 引入koa-router
const router = new Router(); // 創(chuàng)建路由,支持傳遞參數(shù)
// 指定一個(gè)url匹配
router.get('/', async (ctx) => {
ctx.type = 'html';
ctx.body = '<h1>hello world!</h1>';
})
// 調(diào)用router.routes()來組裝匹配好的路由,返回一個(gè)合并好的中間件
// 調(diào)用router.allowedMethods()獲得一個(gè)中間件,當(dāng)發(fā)送了不符合的請求時(shí),會返回 `405 Method Not Allowed` 或 `501 Not Implemented`
app.use(router.routes());
app.use(router.allowedMethods({
// throw: true, // 拋出錯(cuò)誤,代替設(shè)置響應(yīng)頭狀態(tài)
// notImplemented: () => '不支持當(dāng)前請求所需要的功能',
// methodNotAllowed: () => '不支持的請求方式'
}));
koa-router 不同請求方式
Koa-router 請求方式: get 、 put 、 post 、 patch 、 delete 、 del ,而使用方法就是 router.方式() ,比如 router.get() 和 router.post() 。而 router.all() 會匹配所有的請求方法。
// 指定一個(gè)url匹配
router.get('/test', async (ctx) => {
ctx.type = 'html';
ctx.body = '<h1>hello world!</h1>';
})
router.get("/user", async (ctx) => {
ctx.body = '叫我詹躲躲';
})

新建router/index.js 路由文件夾
// router/index.js
const Router = require('koa-router')
const router = new Router()
//接口函數(shù)
class UserController {
// 新增一條數(shù)據(jù)
async getUserName(ctx) {
ctx.body = {
code: 200,
message: '叫我詹躲躲',
type: 'warning'
}
}
}
//實(shí)例
const userController = new UserController()
// 測試
router.get('/test', userController.getUserName)
module.exports = router
測試一下

安裝中間件 koa2-cors
cors跨域資源共享是一種機(jī)制,用來允許不同源服務(wù)器上的指定資源可以被特定的Web應(yīng)用訪問。
cors 安裝
npm install koa-cors --save
cors 使用
//app.js
const Cors = require('koa2-cors')
app.use(Cors())
koa連接數(shù)據(jù)庫(mysql)
需要安裝sql依賴;
npm install mysql --save
SQL配置
新建一個(gè) sql文件夾,主要用于存放sql的各種操作;
sql/config.js
const mysqlConfig = {
user: "Koa", //賬號
password: "Koa", //密碼
database: "Koa", //數(shù)據(jù)庫
host: "122.112.172.87", //服務(wù)器地址
port: 3306, //數(shù)據(jù)庫端口
timezone: '08:00'
};
module.exports = mysqlConfig;
koa封裝sql數(shù)據(jù)庫query函數(shù)
//sql/query.js
const mysql = require("mysql");
const config = require("./config");
//創(chuàng)建連接池
const pool = mysql.createPool(config);
const query = (sql, val) => {
return new Promise((resolve, reject) => {
pool.getConnection(function (err, connection) {
if (err) {
reject(err);
} else {
connection.query(sql, val, (err, fields) => {
if (err) {
reject(err);
} else {
resolve(fields);
}
connection.release();
});
}
});
});
};
module.exports = { query };
新增接口 - 用戶信息注冊 和 登錄
新建兩個(gè)文件夾 controller 和 model
controller主要存放操作和數(shù)據(jù)處理的一些邏輯
// controller/userController.js
// 用戶注冊
const User = require('../model/userModel')
class UserController {
// 用戶注冊
async register(ctx) {
let { name, tel, password } = ctx.request.body
const names = await User.getUser(name) //用戶名是否重復(fù)
const tels = await User.getTel(tel) //手機(jī)號是否重復(fù)
if (tels.length > 0) {
ctx.body = { type: 'warning', message: '該手機(jī)號已注冊' }
} else {
if (names.length > 0) {
ctx.body = { type: 'error', message: '用戶名已存在' }
} else {
await User.insert(name, tel, password)
ctx.body = { type: 'success', code: 0, message: '注冊成功' }
}
}
}
// 登錄
async login(ctx) {
let tel = ctx.request.body.tel
let password = ctx.request.body.password
const res = (await User.getTel(tel))[0]
if (res) {
if (res.password == password) {
ctx.body = {
code: 0,
data: {
name: res.name,
tel: res.tel
},
message: '登錄成功',
type: 'success'
}
} else {
ctx.body = { type: 'error', message: '用戶名或密碼不正確' }
}
} else {
ctx.body = { type: 'error', message: '用戶名不存在' }
}
}
}
module.exports = new UserController()
model中操作數(shù)據(jù)庫的函數(shù)(包含數(shù)據(jù)庫語句)
// model/userModel.js
const query = require('../sql/query')
class UserModel {
//獲取用戶
async getUser(name) {
return await query(`SELECT * FROM user WHERE name = '${name}'`)
}
//獲取用戶手機(jī)號
async getTel(tel) {
return await query(`SELECT * FROM user WHERE tel = '${tel}'`)
}
//用戶注冊
async insert(name, tel, password) {
return await query(`INSERT INTO user(name, tel, password) VALUES('${name}', '${tel}', '${password}')`)
}
}
module.exports = new UserModel()
在router路由文件里面注冊
//router/index.js
const Router = require('koa-router')
const router = new Router()
//用戶
const UserController = require('../controller/UserController')
//用戶注冊
router.post('/register', UserController.register)
//用戶信息登錄
router.post('/login', UserController.login)
module.exports = router
接口調(diào)用
使用post請求就可以調(diào)用 /register 和 /login兩個(gè)接口啦;當(dāng)然也可以再封裝其他更多的接口。
結(jié)尾
到此 用戶的注冊和登錄接口就寫完了。后續(xù)繼續(xù)其他功能添加。有興趣的可以查看源碼 源碼地址,一起學(xué)習(xí),一起加油。我是叫我詹躲躲,很高興認(rèn)識你。