Use TypeScript to verify runtime data

Leon
中文

background

For front-end programmers, the common development process is:

  1. Front-end and back-end convention interface
  2. The backend gives the interface document
  3. Write TypeScript type definitions based on the interface
  4. 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:

  1. Convert TypeScript type definition to JSON Schema
  2. 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 is obeject
  • There are four attributes- properties

    • name : The type is string
    • age : The type is number
    • hobby : The type is Array<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 Schema

  • package.json added scripts :

    "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.
阅读 545

前端之路
前端的学习记录
1.4k 声望
1k 粉丝
0 条评论
你知道吗?

1.4k 声望
1k 粉丝
宣传栏