diff --git a/.vitepress/config.mts b/.vitepress/config.mts index 90afcc1..aaae334 100644 --- a/.vitepress/config.mts +++ b/.vitepress/config.mts @@ -79,7 +79,8 @@ function sidebarDocs(): DefaultTheme.SidebarItem[] { { text: 'Inbound Plugins', items: [ - { text: 'Function', link: 'docs/plugin/function' } + { text: 'Function', link: 'docs/plugin/function' }, + { text: 'JSONSchema-Validator', link: 'docs/plugin/jsonschema-validator' }, ] }, { diff --git a/docs/plugin/jsonschema-validator/index.md b/docs/plugin/jsonschema-validator/index.md new file mode 100644 index 0000000..85d8e30 --- /dev/null +++ b/docs/plugin/jsonschema-validator/index.md @@ -0,0 +1,131 @@ +# Overview +JSONSchema Validator plugin allows you to validate the event request body before delivery to the endpoint. With predefined a [JSON Schema](https://json-schema.org/overview/what-is-jsonschema) definition, it ensures that the incoming data adheres to the expected structure and format, enhancing data integrity and reliability. + +If the validation fails, the event will not be delivered to the endpoint, and an error response will be returned to the sender. + + +# Validation +## Request Body Structure Requirement +The request body is expected to be a JSON object with the following structure: + +```json +{ + "event_type": "string", + "data": { } +} +``` + +- The `data` field will be validated against the corresponding JSON Schema defined for the `event_type`, if no schema is defined for the `event_type`, the `default_schema` will be used if provided. if neither is available, the request will be considered valid. +- The plugin is suggested to be used together with the [Function](../function/index.md) plugin to transform the payload into the expected structure before validation. + + +## Request Body JSON Schema Definition +1. `draft`: the JSON Schema draft version, currently supports `6`. +2. `default_schema` (optional): a default JSON Schema to be used when the `event_type` does not define a specific schema. +3. `schemas`: the JSON Schemas definitions mapped by `event_type`, where each key is an `event_type` and the value is the corresponding JSON Schema. + +| Parameter | Type | Required | Description | Default| +| --------------- | ------ | -------- | ------------------------------------------------ |--------| +| draft | string | Yes | The JSON Schema draft version | `6` | +| default_schema | object | No | A default JSON Schema to use for same definitions of multiple `event_type` | `null` | +| schemas | object | Yes | A mapping of event types to their corresponding JSON Schemas. | `{event_type:jsonschema}` | + +# Examples + +## Configuration Example +```yaml +plugins: + - name: jsonschema-validator + config: + draft: "6" + default_schema: | + { + "type": "object", + "properties": { + "id": { "type": "string" }, + "created_at": { "type": "string", "format": "date-time" } + }, + "required": ["id", "created_at"] + } + schemas: + user.created: | + { + "type": "object", + "properties": { + "user_id": { "type": "string" }, + "email": { "type": "string", "format": "email" } + }, + "required": ["user_id", "email"] + } +``` + +## Event Request Body Example +```json +{ + "event_type": "user.created", + "data":{ + "user_id": "uuid-1234", + "email": "test@example.com" + } +} +``` + + +# Configuration + +::: code-group + +```shell [Admin API] +curl -X POST 'http://localhost:8080/workspaces/default/plugins' \ +--header 'Content-Type: application/json' \ +--data '{ + "name": "jsonschema-validator", + "source_id": "{source_id}", + "config": { + "draft": "6", + "schemas": { + "user.created": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "amount": { "type": "integer", "minimum": 1 }, + "currency": { "type": "string", "minLength": 3, "maxLength": 6 } + }, + "required": ["id", "amount", "currency"] + } + } +}' +``` + +```yaml [Declarative] +sources: + - name: default-source + path: / + methods: ["POST"] + plugins: + - name: "jsonschema-validator" + config: + draft: "6" + schemas: + charge.succeeded: + schema: | + { + "type": "object", + "properties": { + "id": { "type": "string" }, + "amount": { "type": "integer", "minimum": 1 }, + "currency": { "type": "string", "minLength": 3, "maxLength": 6 } + }, + "required": ["id", "amount", "currency"] + } + +``` +::: + +## Limitations +- Only supports JSON request bodies with `Content-Type: application/json`. +- Only validates JSON request bodies that contain both `event_type` and `data` fields. +- Only supports JSON Schema defintions up to [Draft 6](https://json-schema.org/draft-06), other drafts are WIP. + + + diff --git a/package-lock.json b/package-lock.json index f89c810..758834c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,7 @@ "packages": { "": { "devDependencies": { - "vitepress": "2.0.0-alpha.12" + "vitepress": "^2.0.0-alpha.12" } }, "node_modules/@babel/helper-string-parser": { diff --git a/package.json b/package.json index 06fe366..9b05455 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,6 @@ "docs:preview": "vitepress preview" }, "devDependencies": { - "vitepress": "2.0.0-alpha.12" + "vitepress": "^2.0.0-alpha.12" } }