From 75a20047344b599e7fa0a691084a375d5f8f32e4 Mon Sep 17 00:00:00 2001 From: Bobby Yu Date: Fri, 14 Mar 2025 15:16:32 -0700 Subject: [PATCH 1/3] add docs for field level validation --- src/directory/directory.mjs | 3 + .../data/field-level-validation/index.mdx | 86 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx diff --git a/src/directory/directory.mjs b/src/directory/directory.mjs index 937df52c6dd..398a35cd546 100644 --- a/src/directory/directory.mjs +++ b/src/directory/directory.mjs @@ -346,6 +346,9 @@ export const directory = { }, { path: 'src/pages/[platform]/build-a-backend/data/enable-logging/index.mdx' + }, + { + path: 'src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx' } ] }, diff --git a/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx b/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx new file mode 100644 index 00000000000..195063d1fb2 --- /dev/null +++ b/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx @@ -0,0 +1,86 @@ +import { getCustomStaticPath } from '@/utils/getCustomStaticPath'; + +export const meta = { + title: 'Field level validation', + description: 'Learn how to enable field level validation in your model schema', + platforms: [ + 'android', + 'angular', + 'flutter', + 'javascript', + 'nextjs', + 'react', + 'react-native', + 'swift', + 'vue' + ] +}; + +export function getStaticPaths() { + return getCustomStaticPath(meta.platforms); +} + +export function getStaticProps(context) { + return { + props: { + platform: context.params.platform, + meta + } + }; +} + +You can enable field level validation in your model schema by chaining a `validate` function to the field. + +## Examples + +```ts title="amplify/data/resource.ts" +const schema = a.schema({ + Todo: a.model({ + content: a.string().validate(v => + v + .minLength(1, 'Content must be at least 1 character long') + .maxLength(100, 'Content must be less than 100 characters') + .matches('^[a-zA-Z0-9\\\\s]+$', 'Content must contain only letters, numbers, and spaces') + ) + }) + .authorization(allow => [allow.publicApiKey()]) +}); +``` + +## Supported validators + +### String Validators +For `string` fields: + +| Validator | Description | Parameters | Example | +| --- | --- | --- | --- | +| `minLength` | Validates that a string field has at least the specified length | • `length`: The minimum length required
• `errorMessage`: Optional custom error message | `a.string().validate(v => v.minLength(5, 'String must be at least 5 characters'))` | +| `maxLength` | Validates that a string field does not exceed the specified length | • `length`: The maximum length allowed
• `errorMessage`: Optional custom error message | `a.string().validate(v => v.maxLength(100, 'String must be at most 100 characters'))` | +| `startsWith` | Validates that a string field starts with the specified prefix | • `prefix`: The prefix the string must start with
• `errorMessage`: Optional custom error message | `a.string().validate(v => v.startsWith("prefix-", 'String must start with prefix-'))` | +| `endsWith` | Validates that a string field ends with the specified suffix | • `suffix`: The suffix the string must end with
• `errorMessage`: Optional custom error message | `a.string().validate(v => v.endsWith("-suffix", 'String must end with -suffix'))` | +| `matches` | Validates that a string field matches the specified regex pattern using the **Java regex engine**. See notes below. | • `pattern`: The regex pattern the string must match
• `errorMessage`: Optional custom error message | `a.string().validate(v => v.matches("^[a-zA-Z0-9]+$", 'String must match the pattern'))` | + + + +**Note:** Our schema transformer uses the Java regex engine under the hood. Because of how TypeScript processes string literals, you must quadruple-escape special regex characters in your schema. In a TypeScript string literal, writing `\\\\s` produces the string `\\s`, which is the correct form for the Java regex engine. If you write `\\s`, it produces `\s`, which is invalid. Therefore, for the `matches` validator, ensure you use quadruple-escaping. For example: +`a.string().validate(v => v.matches("^[a-zA-Z0-9\\\\s]+$", 'Content must contain only letters, numbers, and spaces'))` + + + +### Numeric Validators +For `integer` and `float` fields: + +| Validator | Description | Parameters | Example | +| --- | --- | --- | --- | +| `gt` | Validates that a numeric field is greater than the specified value | • `value`: The value the field must be greater than
• `errorMessage`: Optional custom error message | `a.integer().validate(v => v.gt(10, 'Must be greater than 10'))` | +| `gte` | Validates that a numeric field is greater than or equal to the specified value | • `value`: The value the field must be greater than or equal to
• `errorMessage`: Optional custom error message | `a.integer().validate(v => v.gte(10, 'Must be at least 10'))` | +| `lt` | Validates that a numeric field is less than the specified value | • `value`: The value the field must be less than
• `errorMessage`: Optional custom error message | `a.integer().validate(v => v.lt(10, 'Must be less than 10'))` | +| `lte` | Validates that a numeric field is less than or equal to the specified value | • `value`: The value the field must be less than or equal to
• `errorMessage`: Optional custom error message | `a.integer().validate(v => v.lte(10, 'Must be at most 10'))` | +| `positive` | Validates that a numeric field is positive | • `errorMessage`: Optional custom error message | `a.integer().validate(v => v.positive('Must be positive'))` | +| `negative` | Validates that a numeric field is negative | • `errorMessage`: Optional custom error message | `a.integer().validate(v => v.negative('Must be negative'))` | + + + +**Note:** Currently, we only support validation on **non-array** fields of type `string`, `integer`, and `float`. + + From 5591fc0a5eddd9f0adf41494a661b4dd2e47fe28 Mon Sep 17 00:00:00 2001 From: bobbyu99 Date: Fri, 14 Mar 2025 15:27:01 -0700 Subject: [PATCH 2/3] chore: use `field-level validation` in description Co-authored-by: josef --- .../build-a-backend/data/field-level-validation/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx b/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx index 195063d1fb2..5a9320af10a 100644 --- a/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx +++ b/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx @@ -29,7 +29,7 @@ export function getStaticProps(context) { }; } -You can enable field level validation in your model schema by chaining a `validate` function to the field. +You can enable field-level validation in your model schema by chaining a `validate` function to the field. ## Examples From 861284e22764406a9e1db0a699ffb88b207c68dc Mon Sep 17 00:00:00 2001 From: bobbyu99 Date: Fri, 14 Mar 2025 15:27:11 -0700 Subject: [PATCH 3/3] chore: use `field-level validation` in title Co-authored-by: josef --- .../build-a-backend/data/field-level-validation/index.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx b/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx index 5a9320af10a..d0c60452ff6 100644 --- a/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx +++ b/src/pages/[platform]/build-a-backend/data/field-level-validation/index.mdx @@ -1,7 +1,7 @@ import { getCustomStaticPath } from '@/utils/getCustomStaticPath'; export const meta = { - title: 'Field level validation', + title: 'Field-level validation', description: 'Learn how to enable field level validation in your model schema', platforms: [ 'android',