To build backend API, one of the problem is validate the external data. Because the incoming data is not necessary valid. The invalid data might come from user input, wrong call of API in frontend. It might also come from malicious attackers. Thus, validation in backend is neccessary no matter frontend did it or not.
Since I’m using Typescript to build backend in Todo project, it would reduce the redundancy of code if I can make use of existing type definition in type definition. This post introduces several approaches for data validation categorized by using JSON schema or not. In my project, I tried the approach that converting Typescript types to JSON schema.
Packages
- typescript-json-schema: Generate json-schemas from Typescript sources.
- ajv: JSON schema validator
Approach
- Use
typescript-json-schema
to pre-compile existing type to JSON schema. - Use
ajv
to make use of the schema from1
to validate the request data.
Code
- Typescript to JSON schema
In my project, I store types used in Web API in common folder to use them both in frontend code and backend code.
After write validation types insrc/apiTypes
, the following command inpackage.json
is used to convert typescript to JSON schema file. (useinstall
command name because it would be called afternpm install
. Please refer to lifecycle scripts)The benefit of1
2
3"scripts": {
"install": "typescript-json-schema src/apiTypes.ts * --noExtraProps --out src/schema.json"
},typescript-json-schema
is that it allows using annotations to enhance the typescript properties in convertion. Like the following:1
2
3
4
5
6
7
8export interface TodoItem {
/**
* @minLength 0
* @maxLength 100
*/
text: string,
state: TodoItemState,
} - Validation with JSON schema
After export JSON schema object fromcommon
, we can use it withajv
:Then, the data could be validated like this:1
2
3
4
5const ajv = new Ajv({
schemaId: 'auto',
allErrors: true,
})
ajv.addSchema(itemSchema, 'item')For details in the URI parameter of1
2const validator = ajv.getSchema('item#/definitions/AddItem')
const result = validator(data)ajv.getSchema
function, please refer to the structuring complex schema