preface

Our defense here only talks about how to defend against the data sent by the back end. For example, you and the back end agree that our data format is as follows:

{
    data: { // Data requires an object
        personInfo: { // personInfo requires an object
            name: 'Joe'.// The personInfo attribute must have a name attribute and be a string
            age: 12.// The personInfo attribute must have an age attribute and be a number
        },
        ...XXX // Other attributes are omitted
    },  
    success: 0.0 indicates success. 1 indicates failure
}
Copy the code

If we want to use back-end data, I believe most of our front-end colleagues will write such code

// Simulate back-end data
const mockData = {
    data: { // Data requires an object
        personInfo: { // personInfo requires an object
            name: 'Joe'.// The personInfo attribute must have a name attribute and be a string
            age: 12.// The personInfo attribute must have an age attribute and be a number
        },
        ...XXX // Other attributes are omitted
    },  
    success: 0.0 indicates success. 1 indicates failure
}
Copy the code

Business use

// Check if it is an object
const isObj = (obj) = > Object.prototype.toString.call(obj).toLowerCase() == "[object object]";


if(mockData && mockData.data && isObj(mockData.data) && mockData.data.personInfo && isObj(mockData.data.personInfo)){ Only here can we safely use mockData.data.personinfo data}Copy the code

Some of you can use es6, right? The. Operator simplifies the above, as follows:

if(mockData? .data? .personInfo && isObj(mockData.data) && isObj(mockData.data.personinfo)){here you can use mockData.data.personinfo data with confidence}Copy the code

It seems a lot simpler, but we are defending and making all kinds of if judgments, which is really annoying, because the validation should be done in the Service layer, which is the fetch library where we request the data, or the XHR library in Axios. We added validation in the business layer, which itself does not meet the single responsibility principle.

solution

So how to let the service layer to do this, we can each request data, in the service layer to do a check, if the data format does not meet the format we discussed with the backend, then directly throw the wrong, do not go behind the logic.

In other words, we need to make sure that the data returned by the back end is 100% satisfactory so that the front end does not make defensive if judgments. (This is the perfect way to throw the pot to the back! The point! The point! The point!)

Some people say you can use typescript to do this, but it doesn’t work. Typescript only works at compile time, and when you pack it, the validation disappears. How can you make it work after you pack it?

Class – the validator very sweet

The solution was to use a library called class-Validator, which is basically a dependency library for simplified validation that must be used in conjunction with typescript because of decorators.

Usage:

import {validate, ValidateNested,Equals, Length, IsNotEmpty, IsNumber} from "class-validator";

// Construct a user type, the information for personInfo
// This class can be used both as typescript type validation and as class-validator
class User {
    @Length(10.20, {message: 'Name cannot be less than 10 and cannot be greater than 20'})
    @IsNotEmpty({message:'Name cannot be null'})
    name: string;

    @IsNumber({message:'Age field must be of type number'})
    age: number;
}

 class Data {
    @ValidateNested()
    user: User;

    constructor() {
        this.user = newUser(); }}class ResponseData {
    @ValidateNested()
    data: Data;

    @Equals(0)
    success: number

    constructor() {
        this.data = newData(); }}let data = {
    data: {
        personInfo: {
            name: 'Joe'.age: 12,}},success: 0.0 indicates success. 1 indicates failure
}
Copy the code

Finally, verify the data

let post = new ResponseData();


validate(post).then(errors= > {
    if (errors.length > 0) {
        console.log(errors);
    } else {
        console.log("Success!); }})Copy the code

The business layer is used as a certain data, and the defensive judgment of back-end data needs to be used at a separate level, which will make the code simpler and more consistent with the single principle.