background
For front-end programmers, the common development process is:
- Front-end and back-end convention interface
- The backend gives the interface document
- Write TypeScript type definitions based on the interface
- Development is completed for joint debugging
Although everything went well, it still overturned after going online. js reported an error: cannot read the property 'xx' of null
. Obviously, the front end did not handle null values. Let's take the TT. But looking back at the interface documentation, I agreed with the back-end classmates to return the object, but actually returned null
. This pot cannot be carried alone. So how can we find this kind of problem as early as possible? One solution is:
- Convert TypeScript type definition to JSON Schema
- Use JSON Schema to verify data correctness
demo made for the above scheme
JSON Schema
JSON Schema is a JSON object used to describe and verify the format of JSON objects. For example, the following JSON Schema:
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"age": {
"type": "number"
},
"hobby": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"age",
"hobby",
"name"
],
"$schema": "http://json-schema.org/draft-07/schema#",
}
It describes such a JSON object:
- Type-
type
isobeject
There are four attributes-
properties
name
: The type isstring
age
: The type isnumber
hobby
: The type isArray<string>
- Is the attribute mandatory-
required
:name
,age
,hobby
are all required
The following JSON object meets this JSON Schema:
{
"name": "Tom",
"age": 1,
"hobby": ["coding"]
}
It can be seen that JSON Schema is still well understood, but its description grammar still has a certain learning cost. It is strongly recommended to learn the related grammar example jsonschema library. Understanding JSON Schema .
With JSON Schema, how to use it to verify the legality of JSON objects? jsonschema library just mentioned is used here. A simple usage example is as follows:
var Validator = require('jsonschema').Validator;
var v = new Validator();
var instance = 4;
var schema = {"type": "number"};
console.log(v.validate(instance, schema));
It is now possible to verify whether the format of the data returned by the backend is correct according to the JSON Schema, but it is unrealistic to manually write JSON Schema for each interface. We naturally think about whether the interface type definition of TypeScript can be converted to JSON Schema?
TypeScript Interface -> JSON Schema
Fortunately, the typescript-json-schema library has helped us solve this problem. Here is a simple usage example:
import path from "path";
import * as TJS from "typescript-json-schema";
const settings: TJS.PartialArgs = {
required: true
};
// optionally pass ts compiler options
const compilerOptions: TJS.CompilerOptions = {
strictNullChecks: true
};
// 解析接口定义文件:index.ts
const program = TJS.getProgramFromFiles(
[path.join(__dirname, './apis/index.ts')],
compilerOptions,
);
// 将"IApi1"这个interface转为schema,传入"*"将转换全部interface
let schema = TJS.generateSchema(program, "IApi1", settings) || {};
After a meal, you can convert the following interface
into the sample JSON Schema given at the beginning of the article:
interface IApi1 {
name: string;
age: number;
hobby: string[];
}
Then use node to save the schema just obtained as a json file:
fs.writeFileSync(path.join(__dirname, "./json-schema", "schema.json"), schema);
Then you can use the corresponding JSON Schema to verify the back-end data:
import { Validator } from 'jsonschema'
const apiSchema = require('./json-schema/schema.json')
const v = new Validator();
Api1().then(res => {
const validateRes1 = v.validate(res, apiSchema)
console.log(validateRes1);
});
The complete example can be seen: demo
Practice in engineering
1. How to organize scattered interface type definitions?
My personal preference is apis.ts
file uniformly, so that this one file can be processed when converting the JSON Schema.
2. How to automatically convert the type definition to JSON Schema?
Use husky
to perform the conversion in the pre-commit
stage, and further use lint-staged
determine whether the current submission involves changes to the interface definition file, and then perform the conversion if there are changes.
About the writing of the script:
First create the script
touch scripts/transfer.js
transfer.js
to write the logic of TS to JSON Schemapackage.json
addedscripts
:"scripts": { "transfer": "node scripts/transfer.js" }
Or execute the script
pre-commit
3. When to verify the data?
Here I think of two scenarios:
- Production: For some key interfaces, the verification logic is called after the interface returns data. If there is an error in the verification, two things need to be done: The first is to convert the wrong data to the correct backup data to prevent the page from hanging; The second is to report errors;
- When testing: Write various test cases to test the back-end interface and verify the correctness of the returned data, so that there is no need for human eyes to verify whether the data is correct.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。