402 lines
10 KiB
Markdown
402 lines
10 KiB
Markdown
# SchemaValidator Plugin
|
|
|
|
A JSON schema validation plugin for beckn-onix that validates incoming request payloads against pre-defined JSON schemas based on domain, version, and endpoint.
|
|
|
|
## Overview
|
|
|
|
The SchemaValidator plugin provides robust JSON schema validation for beckn-onix requests. It automatically loads and caches JSON schemas from a directory structure and validates incoming payloads based on the context information (domain and version) and the API endpoint.
|
|
|
|
## Features
|
|
|
|
- **Automatic Schema Loading**: Recursively loads all JSON schema files from a specified directory
|
|
- **Context-Aware Validation**: Validates payloads based on domain, version, and endpoint extracted from the request
|
|
- **Schema Caching**: Caches compiled schemas in memory for fast validation
|
|
- **Detailed Error Reporting**: Provides specific validation errors with field paths and messages
|
|
- **Flexible Directory Structure**: Supports nested directory structures for organizing schemas
|
|
- **Domain Normalization**: Handles domain names with colons (e.g., converts `nic2004:52110` to `nic2004_52110`)
|
|
|
|
## Configuration
|
|
|
|
### Plugin Configuration
|
|
|
|
In your beckn-onix configuration file:
|
|
|
|
```yaml
|
|
plugins:
|
|
schemaValidator:
|
|
id: schemavalidator
|
|
config:
|
|
schemaDir: ./schemas # Path to directory containing JSON schema files
|
|
```
|
|
|
|
### Configuration Options
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| `schemaDir` | string | Yes | Path to the directory containing JSON schema files |
|
|
|
|
## Schema Directory Structure
|
|
|
|
The plugin expects a specific directory structure for organizing schemas:
|
|
|
|
```
|
|
schemas/
|
|
├── domain1/
|
|
│ ├── v1.0/
|
|
│ │ ├── search.json
|
|
│ │ ├── select.json
|
|
│ │ └── init.json
|
|
│ └── v2.0/
|
|
│ ├── search.json
|
|
│ └── select.json
|
|
├── nic2004_52110/
|
|
│ └── v1.0/
|
|
│ ├── search.json
|
|
│ └── on_search.json
|
|
└── mobility/
|
|
└── v1.0/
|
|
├── search.json
|
|
├── init.json
|
|
└── confirm.json
|
|
```
|
|
|
|
### Schema File Naming Convention
|
|
|
|
Schemas are organized in a three-level hierarchy:
|
|
1. **Domain**: The domain from the request context (e.g., `retail`, `mobility`, `nic2004_52110`)
|
|
2. **Version**: The version prefixed with 'v' (e.g., `v1.0`, `v2.0`)
|
|
3. **Endpoint**: The API endpoint name (e.g., `search.json`, `on_search.json`)
|
|
|
|
### Schema Key Generation
|
|
|
|
The plugin generates cache keys using the format: `{domain}_{version}_{endpoint}`
|
|
|
|
For example:
|
|
- Domain: `nic2004:52110` → normalized to `nic2004_52110`
|
|
- Version: `1.0` → prefixed to `v1.0`
|
|
- Endpoint: `search`
|
|
- **Final cache key**: `nic2004_52110_v1.0_search`
|
|
|
|
## Schema Validation Process
|
|
|
|
### 1. Request Analysis
|
|
The plugin extracts validation parameters from:
|
|
- **Request payload**: `context.domain` and `context.version`
|
|
- **Request URL**: endpoint name from the URL path
|
|
|
|
### 2. Schema Selection
|
|
Based on the extracted information, it:
|
|
1. Normalizes the domain name (replaces `:` with `_`)
|
|
2. Prefixes version with `v`
|
|
3. Constructs the schema key: `{domain}_{version}_{endpoint}`
|
|
4. Retrieves the corresponding schema from cache
|
|
|
|
### 3. Validation
|
|
Validates the entire request payload against the selected schema using the [jsonschema/v6](https://github.com/santhosh-tekuri/jsonschema) library.
|
|
|
|
## Example Schema Files
|
|
|
|
### Basic Schema Structure
|
|
All schemas should validate the context object:
|
|
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"properties": {
|
|
"context": {
|
|
"type": "object",
|
|
"properties": {
|
|
"domain": {
|
|
"type": "string"
|
|
},
|
|
"version": {
|
|
"type": "string"
|
|
},
|
|
"action": {
|
|
"type": "string"
|
|
},
|
|
"bap_id": {
|
|
"type": "string"
|
|
},
|
|
"bpp_id": {
|
|
"type": "string"
|
|
},
|
|
"transaction_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"message_id": {
|
|
"type": "string",
|
|
"format": "uuid"
|
|
},
|
|
"timestamp": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
}
|
|
},
|
|
"required": ["domain", "version", "action"]
|
|
}
|
|
},
|
|
"required": ["context"]
|
|
}
|
|
```
|
|
|
|
### Search Endpoint Schema Example
|
|
`schemas/retail/v1.0/search.json`:
|
|
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"properties": {
|
|
"context": {
|
|
"type": "object",
|
|
"properties": {
|
|
"domain": {"type": "string"},
|
|
"version": {"type": "string"},
|
|
"action": {"const": "search"}
|
|
},
|
|
"required": ["domain", "version", "action"]
|
|
},
|
|
"message": {
|
|
"type": "object",
|
|
"properties": {
|
|
"intent": {
|
|
"type": "object",
|
|
"properties": {
|
|
"item": {
|
|
"type": "object",
|
|
"properties": {
|
|
"descriptor": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {"type": "string"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"required": ["context", "message"]
|
|
}
|
|
```
|
|
|
|
## Request Payload Format
|
|
|
|
The plugin expects incoming requests to have this structure:
|
|
|
|
```json
|
|
{
|
|
"context": {
|
|
"domain": "retail",
|
|
"version": "1.0",
|
|
"action": "search",
|
|
"bap_id": "example-bap",
|
|
"bpp_id": "example-bpp",
|
|
"transaction_id": "uuid-here",
|
|
"message_id": "uuid-here",
|
|
"timestamp": "2023-06-15T09:30:00.000Z"
|
|
},
|
|
"message": {
|
|
// endpoint-specific payload
|
|
}
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
The plugin provides detailed error reporting for validation failures:
|
|
|
|
### Schema Validation Errors
|
|
When validation fails, the plugin returns a `SchemaValidationErr` with detailed information:
|
|
|
|
```json
|
|
{
|
|
"type": "SCHEMA_VALIDATION_ERROR",
|
|
"errors": [
|
|
{
|
|
"path": "context.action",
|
|
"message": "missing property 'action'"
|
|
},
|
|
{
|
|
"path": "message.intent.item",
|
|
"message": "property 'item' is required"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Common Error Types
|
|
- **Missing Context Fields**: `missing field Domain in context` or `missing field Version in context`
|
|
- **Schema Not Found**: `schema not found for domain: {domain}`
|
|
- **JSON Parse Error**: `failed to parse JSON payload`
|
|
- **Validation Failure**: Detailed field-level validation errors
|
|
|
|
## Usage Examples
|
|
|
|
### 1. Valid Request
|
|
**Request URL**: `POST /search`
|
|
**Payload**:
|
|
```json
|
|
{
|
|
"context": {
|
|
"domain": "retail",
|
|
"version": "1.0",
|
|
"action": "search"
|
|
},
|
|
"message": {
|
|
"intent": {
|
|
"item": {
|
|
"descriptor": {
|
|
"name": "laptop"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
**Schema Used**: `schemas/retail/v1.0/search.json`
|
|
**Result**: ✅ Validation passes
|
|
|
|
### 2. Domain with Special Characters
|
|
**Request URL**: `POST /search`
|
|
**Payload**:
|
|
```json
|
|
{
|
|
"context": {
|
|
"domain": "nic2004:52110",
|
|
"version": "1.0",
|
|
"action": "search"
|
|
},
|
|
"message": {}
|
|
}
|
|
```
|
|
**Schema Used**: `schemas/nic2004_52110/v1.0/search.json`
|
|
**Result**: ✅ Domain normalized automatically
|
|
|
|
### 3. Missing Required Field
|
|
**Request URL**: `POST /search`
|
|
**Payload**:
|
|
```json
|
|
{
|
|
"context": {
|
|
"domain": "retail",
|
|
"version": "1.0"
|
|
// missing "action" field
|
|
},
|
|
"message": {}
|
|
}
|
|
```
|
|
**Result**: ❌ Validation fails with detailed error
|
|
|
|
## Setup Instructions
|
|
|
|
### 1. Directory Setup
|
|
Create your schema directory structure:
|
|
|
|
```bash
|
|
mkdir -p schemas/retail/v1.0
|
|
mkdir -p schemas/mobility/v1.0
|
|
mkdir -p schemas/nic2004_52110/v1.0
|
|
```
|
|
|
|
### 2. Add Schema Files
|
|
Create JSON schema files for each endpoint in the appropriate directories.
|
|
|
|
### 3. Configure Plugin
|
|
Add the schemavalidator plugin to your beckn-onix configuration:
|
|
|
|
```yaml
|
|
plugins:
|
|
schemaValidator:
|
|
id: schemavalidator
|
|
config:
|
|
schemaDir: ./schemas
|
|
```
|
|
|
|
### 4. Start beckn-onix
|
|
The plugin will automatically:
|
|
- Load all schema files during initialization
|
|
- Cache compiled schemas for fast validation
|
|
- Validate incoming requests against appropriate schemas
|
|
|
|
## Best Practices
|
|
|
|
### Schema Design
|
|
1. **Always validate context**: Ensure all schemas validate the required context fields
|
|
2. **Use specific constraints**: Use `const` for exact matches (e.g., action names)
|
|
3. **Define required fields**: Clearly specify which fields are mandatory
|
|
4. **Use format validation**: Leverage built-in formats like `uuid`, `date-time`, `email`
|
|
|
|
### Directory Organization
|
|
1. **Consistent naming**: Use lowercase, underscore-separated names for domains
|
|
2. **Version management**: Keep different versions in separate directories
|
|
3. **Clear endpoint names**: Use descriptive names that match your API endpoints
|
|
|
|
### Error Handling
|
|
1. **Specific schemas**: Create endpoint-specific schemas for better validation
|
|
2. **Meaningful error messages**: Design schemas to provide clear validation feedback
|
|
3. **Test schemas**: Validate your schemas against sample payloads
|
|
|
|
## Testing
|
|
|
|
Run the plugin tests:
|
|
|
|
```bash
|
|
cd pkg/plugin/implementation/schemavalidator
|
|
go test -v ./...
|
|
```
|
|
|
|
## Performance Considerations
|
|
|
|
- **Schema Caching**: Schemas are compiled once during initialization and cached in memory
|
|
- **Fast Validation**: Uses efficient jsonschema library for validation
|
|
- **Memory Usage**: Schemas are kept in memory for the lifetime of the application
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
1. **Schema not found**
|
|
- Verify directory structure matches `domain/version/endpoint.json`
|
|
- Check domain normalization (`:` becomes `_`)
|
|
- Ensure version is prefixed with `v`
|
|
|
|
2. **Schema compilation failed**
|
|
- Validate JSON schema syntax
|
|
- Check for circular references
|
|
- Ensure schema follows JSON Schema Draft 7
|
|
|
|
3. **Validation fails unexpectedly**
|
|
- Compare request payload with schema requirements
|
|
- Check for typos in field names
|
|
- Verify data types match schema expectations
|
|
|
|
### Debug Mode
|
|
|
|
Enable debug logging to see detailed validation information:
|
|
|
|
```yaml
|
|
log:
|
|
level: debug
|
|
```
|
|
|
|
This will show:
|
|
- Schema loading process
|
|
- Cache key generation
|
|
- Validation attempts
|
|
- Error details
|
|
|
|
## Dependencies
|
|
|
|
- [jsonschema/v6](https://github.com/santhosh-tekuri/jsonschema): JSON Schema validation library
|
|
- Standard Go libraries for file system operations
|
|
|
|
## License
|
|
|
|
This plugin follows the same license as the main beckn-onix project.
|