一. RESTful(Representational State Transfer)風格API:
1. 客服服務端(Client-Server)
關注點分離红柱,服務端專注數(shù)據(jù)存儲,提升了簡單性释簿,前端專注用戶界面,提升了可移植性
2. 無狀態(tài)(Stateless)
每次請求必須包括所有信息柬祠,不能依賴上下文信息巨缘,客戶端保留所有會話信息欣鳖,服務端不再保留會話信息
3. 緩存(Cache)
所有信息必須標記為可緩存或不可緩存
4. 統(tǒng)一接口(Uniform Interface)
接口設計盡可能統(tǒng)一,接口與實現(xiàn)解耦
5. 分層系統(tǒng)(Layered System)
每一層只知道相鄰的一層不傅,每一層負責不同的功能安全旅掂,負載均衡
6. 按需代碼
RESTful風格最佳例子:https://developer.github.com/v3/
二.koa基礎使用
1.自定義路由
koa所需工具:nodemon自動重啟
記得取package.json里寫腳本:"start":"nodemon index.js",
斷點調試和查看官網(wǎng)的api:ctx.url ctx.status ctx.method ctx.body
const Koa = require("koa")
const app = new Koa()
app.use(async (ctx) => {
if (ctx.url === '/') {
//處理不同的url
ctx.body = "這是主頁 "
} else if (ctx.url === "/user") {
//處理不同的方法
if (ctx.method === "GET") {
ctx.body = "這是用戶列表頁"
} else if (ctx.method === "POST") {
ctx.body = "創(chuàng)建用戶"
} else {
//方法不允許
ctx.status = 405
}
} else if (ctx.url.match(/\/user\/\w+/)) {
// 解析請求參數(shù)
const userId = ctx.url.match(/\/user\/(\w+)/)[1]
ctx.body = `這是用戶${userId}`
} else {
ctx.status = 404
}
})
app.listen(3000)
2.使用koa-router,不用自定義路由
koa-router實現(xiàn)路由
獲取HTTP請求參數(shù):
- 獲取query(ctx.query). ?q=keyword
- 獲取body(koa-bodyparser||koa-body)
- 獲取header(ctx.header). Accept,Cookie
- 獲取router params(ctx.params). /users/:id
發(fā)送HTTP響應:
- 發(fā)送status(ctx.status)
- 發(fā)送body(ctx.body)
- 發(fā)送header(ctx.set("Allow","get","post"))Allow Content-type
- 實現(xiàn)用戶的增刪改查(get獲取用戶访娶,post新建返回新建用戶商虐,put全部更新,patch局部更新崖疤,delete刪除返回204秘车,options顯示支持什么訪問方法)
常用狀態(tài)碼:
204:刪除用戶后返回,表示成功狀態(tài)響應代碼指示請求已成功戳晌,但沒有內容返回
200:響應成功鲫尊,內容返回
500:運行時錯誤
404:找不到
412:先決條件失敗
422:無法處理的實體,參數(shù)格式不對
const Koa = require("koa")
const Router = require("koa-router")
const app = new Koa()
const router = new Router()
//前綴
const userRouter = new Router({ prefix: "/user" })
const koaBody = require("koa-body")
const parser = require("koa-bodyparser")
//多中間件
const auth = async (ctx, next) => {
// if(ctx.url !== "/user"){
// //沒有權限
// ctx.throw(401)
// }
await next( )
}
router.get("/", (ctx) => {
ctx.body = "這是主頁"
})
//處理不同的url
userRouter.get('/', auth, (ctx) => {
ctx.body = "這是用戶列表"
})
//處理不同的方法 post新建用戶 返回新建的用戶
userRouter.post("/", auth, (ctx) => {
ctx.body = "創(chuàng)建用戶"
})
//解析請求參數(shù) get查列表 返回列表
userRouter.get("/:id", auth, (ctx) => {
//設置header響應頭
ctx.set("Allow","GET,POST")
ctx.body = `這是用戶${ctx.params.id}列表 `
})
//put修改 返回修改的用戶
userRouter.put("/:id", (ctx) => {
ctx.body = `這是用戶${ctx.params.id}`
})
//delete刪除 返回實體沦偎,但是成功
userRouter.delete("/:id", (ctx) => {
ctx.status = 204
})
//注冊中間件
app.use(parser( ))
app.use(router.routes())
app.use(userRouter.routes())
//響應options方法請求疫向,告訴他所支持的請求方法
//405方法不允許咳蔚,支持但沒寫。501方法無法實現(xiàn)搔驼,不存在
app.use(userRouter.allowedMethods())
app.listen(3000)
//http請求參數(shù):
//Query String 如谈火?q=keyword(可選)
//Router Params 如/user/:id(必傳)
//Body,如json,form等conten-type里面會寫到
//Header,如accept舌涨,cookie糯耍,jwt等
//發(fā)送http響應:
//發(fā)送status。如200/400等
//發(fā)送body囊嘉,如json等
//發(fā)送header温技,如allow,content-type等
//1.每個資源的控制器盡量發(fā)在不同的文件里
//2.盡量使用類+類的形式編寫控制器
//3.嚴謹?shù)腻e誤處理
3.錯誤處理和更加合理的目錄結構
錯誤處理:
ctx.throw(422,'文本信息')
koa-json-error:記得隱藏堆棧信息扭粱,在生產環(huán)境的時候
koa-parameter:校驗參數(shù)ctx.verifyParams({name:{type:"string",required:true}})
const Koa = require("koa")
const bodyParser = require("koa-bodyparser")
const app = new Koa()
const routing = require("./routes")
const error = require("koa-json-error")
const parameter = require('koa-parameter')//校驗參數(shù)
//自定義的錯誤處理舵鳞,無法捕獲404信息
// app.use(async (ctx, next) => {
// try {
// await next()
// } catch (error) {
// //斷點
// ctx.status = error.status || error.statusCode || 500
// //返回json格式
// ctx.body = {
// message: error.message
// }
// }
// })
app.use(error({
//定制返回格式
postFormat: (e, { stack, ...rest }) => {//原生的error,應該返回的格式
// "start": "export NODE_ENV='production'&& nodemon app",
return process.env.NODE_ENV === "production" ? rest : { stack, ...rest }
}
}))//koa-json-error中間價處理錯誤琢蛤,404蜓堕,412,500
app.use(bodyParser())//解析請求體
app.use(parameter(app))//校驗參數(shù)博其,傳入app套才,進行全局的使用,全局方法慕淡,比如在create方法中
routing(app)
app.listen(3000, () => { console.log("程序在3000端口啟動了") })
//異常狀況有哪些
//1.運行是錯誤背伴,服務器內部的錯誤500
//2.邏輯錯誤,找不到404峰髓,先決條件失敗412挂据,無法處理的實體(參數(shù)格式不對422)
// 為什么要使用錯誤處理
//1.防止程序掛掉
//2.告訴用戶信息
//3.便于開發(fā)者調試