## What is Form Validation
In the development mode where the frontend and the backend are independent, the frontend and the backend need to implement their own `form validation` logic separately. CabloyJS gives full play to the advantages of full stack development. By defining the configuration information of `JSON schema`, it can support the `form validation` logic of both frontend and backend. At the same time, it also has the `data converting` feature. According to the `JSON schema` configuration information, it automatically converts the `form field` to the data type required by the backend
The authentication mechanism of CabloyJS uses ajv. We suggest you have a preliminary understanding of [ajv](https://github.com/epoberezkin/ajv)
## Definition of Validation
Take the form `formTest` of module `test-party` as an example:
### 1. Definition of Schema
Configure `JSON Schema` of `formTest`, define form fields: `userName`、`password`、`passwordAgain`、`sex`、`language`、`avatar`、`rememberMe`
The field definition in `JSON Schema` has two main purposes:
1. Auto render `form` at frontend
2. Verify form data and convert data type at backend
`src/suite-vendor/test-party/modules/test-party/backend/src/config/validation/schemas.js`
```javascript
schemas.formTest = {
type: 'object',
properties: {
userName: {
type: 'string',
ebType: 'text',
ebTitle: 'Username',
notEmpty: true,
'x-exists': true,
},
password: {
type: 'string',
ebType: 'text',
ebTitle: 'Password',
ebSecure: true,
notEmpty: true,
minLength: 6,
},
passwordAgain: {
type: 'string',
ebType: 'text',
ebTitle: 'Password again',
ebSecure: true,
notEmpty: true,
const: { $data: '1/password' },
},
sex: {
type: 'number',
ebType: 'select',
ebTitle: 'Sex',
ebMultiple: false,
ebOptions: [
{ title: 'Male', value: 1 },
{ title: 'Female', value: 2 },
],
ebOptionsBlankAuto: true,
ebParams: {
openIn: 'page',
closeOnSelect: true,
},
notEmpty: true,
},
language: {
type: 'string',
ebType: 'select',
ebTitle: 'Language',
ebOptionsUrl: '/a/base/base/locales',
ebOptionsUrlParams: null,
ebOptionsBlankAuto: true,
'x-languages': true,
notEmpty: true,
},
avatar: {
type: 'string',
ebType: 'file',
ebTitle: 'Avatar',
ebParams: { mode: 1 },
notEmpty: true,
},
rememberMe: {
type: 'boolean',
ebType: 'toggle',
ebTitle: 'Remember me',
},
},
};
```
|Name|Description|
|--|--|
|type|field type, such as: `string/number/boolean`|
|ebType|field rendering type, used to indicate the type of frontend rendering component, such as `text/toggle/select`|
|ebTitle|field title|
|notEmpty|not empty|
### 2. Definition of Validation
`src/suite-vendor/test-party/modules/test-party/backend/src/meta.js`
```javascript
validation: {
validators: {
formTest: {
schemas: 'formTest',
},
},
keywords: {
'x-languages': keywords.languages,
},
schemas: {
formTest: schemas.formTest,
},
},
```
|Name|Description|
|--|--|
|validation.validators|validator list|
|validation.keywords|keyword list|
|validation.schemas|schema list|
> The relationship between `validator` and `schema`
> - One `validator` can correspond to multiple `schemas`, but in general, only one `schema` is required
## Validation at Backend
Module `a-validation` provides two validation middleware: `validate` and `validation`
### 1. validate
Middleware `validate` automatically performs `validation` and `converting` logic of `form data` according to middleware parameters configured in API route
`src/suite-vendor/test-party/modules/test-party/backend/src/routes.js`
```javascript
{ method: 'post', path: 'kitchen-sink/form-schema-validation/saveValidation', controller: testKitchensinkFormSchemaValidation, middlewares: 'validate',
meta: {
validate: { validator: 'formTest' },
},
},
```
|名称|说明|
|--|--|
|middlewares: 'validate'|Because `validate` is a local middleware, it needs to be explicitly declared|
|meta.validate|middleware parameters|
|meta.validate.module|validator module name|
|meta.validate.validator|validator name|
### 2. validation
The global middleware `validation` injects object `validation` into `ctx.meta`, which is convenient for validation by code
`a-authsimple/backend/src/config/passport/auth.js`
```javascript
// validate
await ctx.meta.validation.validate({
module: 'a-authsimple', validator: 'signin', data: body
});
```
|Name|Description|
|--|--|
|module|module name|
|validator|validator name|
|data|`form data` to be validated|
## Rendering at Frontend
Module `a-components` provides a global Vue component `eb-validate`, which has two main purposes:
1. Render Form
2. Intercept and display the `validation error information` returned by the backend
### 1. Auto Render
The form is automatically rendered by `eb-validate` according to the `schema` information provided by `validator`
`src/suite-vendor/test-party/modules/test-party/front/src/kitchen-sink/pages/form-schema-validation/formSchemaAuto.vue`
```javascript
```
|Name|Description|
|--|--|
|auto|`true`: auto render, `false`: custom render|
|data|form data|
|params|parameters|
|params.module|validator module name|
|params.validator|validator name|
|onPerform|perform backend API route here|
|submit.prevent|respond to submit event|
1. When clicking the button `Save` or responding to the 'Submit` event, invoke the method `perform` of `eb-validate`, thus triggering the `onPerform` of `eb-validate`
3. Invoke the backend API route in `onPerform`. If there are validation errors, they will be displayed automatically
### 2. Custom Render
Customize the layout of form components within `eb-validate`, which can be more targeted and flexible
`src/suite-vendor/test-party/modules/test-party/front/src/kitchen-sink/pages/form-schema-validation/formSchemaCustom.vue`
```javascript
```