## 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 ```