RESTful API 學習(node.js koa)

HTTP options 方法的作用是什麼 ?

  • 檢測服務器所支持的請求方法
    發送options方式請求在返回的請求頭Allow屬性中可以看到支持的請求方法
  • CORS 中的預檢請求
    如果一個網站的其中的一部分接口的一部分方法支持跨域,我們可檢測該方法是否可以跨域

allowedMethods 的作用

  • 代碼:app.use(usersRouter.allowedMethods()) 加上它該路由都將支持options方法
  • 響應 options 方法, 告訴它所支持的請求方法
    在這裏插入圖片描述
    • 若沒有使用此方法使用option方式請求就會報404錯誤
      在這裏插入圖片描述
  • 相應的返回405(不允許)和501(沒實現)
    405: 支持該請求方法但是該接口功能未實現未寫的時候
    501: 不支持該請求方法是返回

RESTful API 最佳實踐–增刪改查應該返回什麼響應?

增加修改返回該對象
刪除返回204狀態碼
實例:

usersRouter.delete('/:id', (ctx) => {
  ctx.status = 204
})

錯誤處理

  • 編程語言或計算機硬件裏的一種機制
  • 處理軟件或信息系統中出現的異常狀況

異常狀況

  • 運行時錯誤, 都返回 500
    建立在語法沒有錯誤的基礎上, 在運行時出現的錯誤, 如請求undefined時錯誤
  • 邏輯錯誤, 如
    找不到(404) .
    先決條件失敗 ( 412 ) : 請求的id不存在
    無法處理的實體 ( 參數格式不對 , 422 ) : 請求體參數格式不對
    等…

爲什麼要用錯誤處理

  • 防止程序掛掉
    try…catch
  • 告訴用戶錯誤信息
    避免用戶不知道錯在哪裏, 體驗較差, 用戶羣體消失
  • 便於開發者調試

操作步驟

  • 製造 404 , 412 , 500 三種錯誤
  1. 404
    在這裏插入圖片描述
  2. 412
  findById(ctx) {
    if(ctx.params.id * 1 >= db.length) { // 不存在id時
      ctx.throw(412, '先決條件失敗, id 大於等於數組長度了')
    }
    ctx.body = { name: 'lilei' }
  }

在這裏插入圖片描述
3. 500

  find(ctx) {
    ctx.body = a.b
  }
  • 瞭解 Koa 自帶的錯誤處理做了什麼

自己編寫錯誤處理中間件

操作步驟

  • 自己編寫錯誤處理中間件
app.use(async(ctx, next) => {
  try {
    await next()
  } catch (err) {
    
// message:"先決條件失敗, id 大於等於數組長度了"
// name:"PreconditionFailedError"
// stack:"PreconditionFailedError: 先決條件失敗, id 大於等於數組長度了
// expose:true
// status:412
// statusCode:412
    ctx.status = err.status || err.statusCode
    ctx.body = {
      message: err.message
    }
  }
})
  1. 500
    ctx.status = err.status || err.statusCode || 500
    在這裏插入圖片描述
  • 製造 404 , 412 , 500 三種錯誤來測試

使用 koa-json-error 進行錯誤處理

在這裏插入圖片描述

使用 koa-parameter 校驗參數(校驗前端表單)

參數不正確, 返回422
app.use(parameter(app))不僅僅是一箇中間件, 可以在ctx加上方法校驗, 可以全局使用,所以傳入app

ctx.verifyParams({
      name: { type: 'string', required: true},
      age: { type: 'number', required: true}
    })

在這裏插入圖片描述

補充:
409: 如新建用戶,發現用戶已存在,拋出錯誤

字段過濾

設計schema默認隱藏部分字段

原返回

{
		"gender": "male",
		"locations": [
			"上海",
			"北京"
		],
		"_id": "5eadafda08d7180ecc1fb330",
		"username": "izhaong",
		"employments": [
			{
				"_id": "5eadb33dfb66404e84c9fa57",
				"company": "biotree"
			}
		],
		"educations": [
			{
				"_id": "5eadb33dfb66404e84c9fa58",
				"school": "皇家機電",
				"major": "釩鈦資源利用技術",
				"diploma": 3,
				"entrance_year": 2014,
				"graduation_year": 2017
			}
		],
		"avatar": "http://localhost:3000/upload/upload_7fb20d056f3d693d4bde34a2b4289783.jpeg",
		"business": "互聯網",
		"headline": "誠意 正心 明理 格物 致知 修身 齊家"
	}

設計

const userSchema = new Schema({
  __v: { type: Number, select: false },
  username: { type: String, required: true },
  password: { type: String, required: true, select: false },
  avatar: { type: String },
  gender: { type: String, enum: ['male', 'femele'], default: 'male', required: true },
  headline: { type: String },
  locations: { type: [{ type: String }], select: false },
  business: { type: String, select: false },
  employments: { type: [{ company: { type: String }, job: { type: String } }], select: false },
  educations: {
    type: [{
      school: { type: String },
      major: { type: String },
      diploma: { type: Number, enum: [1, 2, 3, 4, 5] },
      entrance_year: { type: Number },
      graduation_year: { type: Number }
    }],  
  select: false
  }
})

設計之後

{
	"gender": "male",
	"_id": "5eadafda08d7180ecc1fb330",
	"username": "izhaong",
	"avatar": "http://localhost:3000/upload/upload_7fb20d056f3d693d4bde34a2b4289783.jpeg",
	"headline": "誠意 正心 明理 格物 致知 修身 齊家"
}

通過查詢字符串顯示隱藏字段

mongoose是支持const user = await User.findById(ctx.params.id).select('+educations+business')這種查詢的
所以我們不能寫死
處理得

const { fields } = ctx.query
// f不能爲空 過濾掉
const selectFields = fields.split(';').filter(f => f).map(f => ' +' + f).join('')
// const user = await User.findById(ctx.params.id)
// const user = await User.findById(ctx.params.id).select('+educations+business')
const user = await User.findById(ctx.params.id).select(selectFields)

查詢{{api}}/users/5eadafda08d7180ecc1fb330?fields=educations;business

{
	"gender": "male",
	"_id": "5eadafda08d7180ecc1fb330",
	"username": "izhaong",
	"educations": [
		{
			"_id": "5eadca0728cdd1bf308632de",
			"school": "皇家機電",
			"major": "釩鈦資源利用技術",
			"diploma": 3,
			"entrance_year": 2014,
			"graduation_year": 2017
		}
	],
	"avatar": "http://localhost:3000/upload/upload_7fb20d056f3d693d4bde34a2b4289783.jpeg",
	"business": "互聯網",
	"headline": "誠意 正心 明理 格物 致知 修身 齊家"
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章