最近遇到的案子需要驗證 API 回傳的 JSON 架構,第一時間當然就是去翻 Postman 的文件。
Postman 裡分別用了 tv4 和 Ajv 這兩個函式做為驗證 JSON 結構,就稍微啃了一下四散各地的文件。
首先找到的是 tv4 的 github repo 上的文件:Tiny Validator (for v4 JSON Schema) 。
但是因為範例不大夠,不知道怎麼定義 schema 的部份,又去點了最上面的 json-schema draft v4 的連結,得到第二份文件:JSON Schema: A Media Type for Describing JSON Documents。
第二份文件裡說關於驗證的部份另外在一份文件,於是得到第三份文件:JSON Schema Validation: A Vocabulary for Structural Validation of JSON。
根據第三份文件,可以很簡單堆一些 JSON schema 出來,大概像是這樣:
let schema = {
type: 'object',
required: ['sample', 'error', 'message'],
properties: {
error: {
type: 'boolean',
},
message: {
type: 'string',
},
},
};
堆好 JSON schema 物件之後,就可以直接丟進 tv4.validate()
用。
由於我需要在不同的 API 都存取這個 JSON schema ,於是就利用 Postman 的環境變數把它存起來:
pm.environment.set('sample-schema', JSON.stringify(schema));
存的時候要記得過 JSON.stringify()
,不然會存成 [Object object]
這種悲劇結果。
如果想要存成比較容易閱讀的 JSON ,就利用 stringify()
的第二個參數達成:
pm.environment.set('sample-schema', JSON.stringify(schema, null, 4));
讀的時候也要記得用 JSON.parse()
處理成物件,不然會是另一場悲劇:
let schemaObj = JSON.parse(pm.environment.get('sample-schema'));
在堆 JSON schema 物件的過程中又翻到一份不錯的文件:Understanding JSON Schema ,這時發現文件已經是 7.0 了,但是用的卻不是 tv7
而是 tv4
,總覺得哪裡怪怪的,結果在 Postman Sandbox 文件中的 Commonly used libraries and utilities 翻到 tv4 已經被 Postman 的作者加上了 deprecated …好吧,只好換成 Ajv 了。
Ajv 在宣告的時候會需要指定一些選項,我選了 allErrors
, jsonPointers
和範例中的 logger
:
let Ajv = require('Ajv'),
ajv = new Ajv({
allErrors: true,
jsonPointers: true,
logger: console,
}),
sample = 'sample';
然後因為 Ajv 支援 v7 ,所以可以用 const
來指定特定的參數要回傳的值:
let schema = {
properties: {
error: {
const: false,
},
},
};
由於我需要檢查的 JSON Object 層級有點深,所以利用了 $ref
來存取:
let schema = {
definitions: {
third: {
type: 'array',
items: {
const: 'example',
},
},
second: {
type: 'array',
items: {
type: 'object',
properties: {
third: {
$ref: '#/definitions/third',
},
},
},
},
},
properties: {
first: {
$ref: '#/definitions/second',
},
},
};
最後在 JSON schema 加上建議的 $schema
和 $id
,測試了一下沒什麼問題。
試的過程中踩的幾個雷有:
- JSON 存成全域變數。因為下載環境變數時找不到變數,測試死一片⋯
- JSON 讀取時沒用
JSON.parse()
,結果 Ajv 一直回我no schema with key or ref
然後加上一整串 JSON string ,測試當然又死一片,而且因為錯誤訊息看不出問題在哪,直到一行一行檢查才發現⋯
留言列表