The fix in the previous PR is no longer required because the protocol is changed to solve the root cause, reverting this change.
Schemav2Validator Plugin
Validates Beckn protocol requests against OpenAPI 3.1 specifications using kin-openapi library.
Features
- Validates requests against OpenAPI 3.1 specs
- Supports remote URL and local file loading
- Automatic external $ref resolution
- TTL-based caching with automatic refresh
- Generic path matching (no hardcoded paths)
- Direct schema validation without router overhead
- Extended schema validation for domain-specific objects with
@contextreferences
Configuration
schemaValidator:
id: schemav2validator
config:
type: url
location: https://example.com/openapi-spec.yaml
cacheTTL: "3600"
extendedSchema_enabled: "true"
extendedSchema_cacheTTL: "86400"
extendedSchema_maxCacheSize: "100"
extendedSchema_downloadTimeout: "30"
extendedSchema_allowedDomains: "beckn.org,example.com"
Configuration Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
type |
string | Yes | - | Type of spec source: "url" or "file" ("dir" reserved for future) |
location |
string | Yes | - | URL or file path to OpenAPI 3.1 spec |
cacheTTL |
string | No | "3600" | Cache TTL in seconds before reloading spec |
extendedSchema_enabled |
string | No | "false" | Enable extended schema validation for @context objects |
extendedSchema_cacheTTL |
string | No | "86400" | Domain schema cache TTL in seconds |
extendedSchema_maxCacheSize |
string | No | "100" | Maximum number of cached domain schemas |
extendedSchema_downloadTimeout |
string | No | "30" | Timeout for downloading domain schemas |
extendedSchema_allowedDomains |
string | No | "" | Comma-separated domain whitelist (empty = all allowed) |
How It Works
Initialization (Load Time)
Core Protocol Validation Setup:
- Load OpenAPI Spec: Loads main spec from
location(URL or file) with external$refresolution - Build Action Index: Creates action→schema map for O(1) lookup by scanning all paths/methods
- Validate Spec: Validates OpenAPI spec structure (warnings logged, non-fatal)
- Cache Spec: Stores loaded spec with
loadedAttimestamp
Extended Schema Setup (if extendedSchema_enabled: "true"):
5. Initialize Schema Cache: Creates LRU cache with maxCacheSize (default: 100)
6. Start Background Refresh: Launches goroutine with two tickers:
- Core spec refresh every
cacheTTLseconds (default: 3600) - Extended schema cleanup every
extendedSchema_cacheTTLseconds (default: 86400)
Request Validation (Runtime)
Core Protocol Validation (always runs):
- Parse Request: Unmarshal JSON and extract
context.action - Lookup Schema: O(1) lookup in action index (built at load time)
- Validate: Call
schema.Value.VisitJSON()with:- Required fields validation
- Data type validation (string, number, boolean, object, array)
- Format validation (email, uri, date-time, uuid, etc.)
- Constraint validation (min/max, pattern, enum, const)
- Nested object and array validation
- Return Errors: If validation fails, format and return errors
Extended Schema Validation (if extendedSchema_enabled: "true" AND core validation passed):
5. Scan for @context: Recursively traverse message field for objects with @context and @type
6. Filter Core Schemas: Skip objects with /schema/core/ in @context URL
7. Validate Each Domain Object:
- Check domain whitelist (if
allowedDomainsconfigured) - Transform
@contextURL:context.jsonld→attributes.yaml - Load schema from URL/file (check cache first, download if miss)
- Find schema by
@type(direct match orx-jsonld.@typefallback) - Strip
@contextand@typemetadata from object - Validate remaining data against domain schema
- Prefix error paths with object location (e.g.,
message.order.field)
- Return Errors: Returns first validation error (fail-fast)
Action-Based Matching
The validator uses action-based schema matching, not URL path matching. It searches for schemas where the context.action field has an enum constraint containing the request's action value.
Example OpenAPI Schema
paths:
/beckn/search:
post:
requestBody:
content:
application/json:
schema:
properties:
context:
properties:
action:
enum: ["search"] # ← Matches action="search"
Matching Examples
| Request Action | Schema Enum | Match |
|---|---|---|
search |
enum: ["search"] |
✅ Matches |
select |
enum: ["select", "init"] |
✅ Matches |
discover |
enum: ["search"] |
❌ No match |
on_search |
enum: ["on_search"] |
✅ Matches |
External References
The validator automatically resolves external $ref references in OpenAPI specs:
# Main spec at https://example.com/api.yaml
paths:
/search:
post:
requestBody:
content:
application/json:
schema:
$ref: 'https://example.com/schemas/search.yaml#/SearchRequest'
The loader will automatically fetch and resolve the external reference.
Example Usage
Remote URL
schemaValidator:
id: schemav2validator
config:
type: url
location: https://raw.githubusercontent.com/beckn/protocol-specifications/master/api/beckn-2.0.0.yaml
cacheTTL: "7200"
Local File
schemaValidator:
id: schemav2validator
config:
type: file
location: ./validation-scripts/l2-config/mobility_1.1.0_openapi_3.1.yaml
cacheTTL: "3600"
With Extended Schema Validation
schemaValidator:
id: schemav2validator
config:
type: url
location: https://raw.githubusercontent.com/beckn/protocol-specifications-new/refs/heads/draft/api-specs/beckn-protocol-api.yaml
cacheTTL: "3600"
extendedSchema_enabled: "true"
extendedSchema_cacheTTL: "86400"
extendedSchema_maxCacheSize: "100"
extendedSchema_downloadTimeout: "30"
extendedSchema_allowedDomains: "raw.githubusercontent.com,schemas.beckn.org"
At Load Time:
- Creates LRU cache for domain schemas (max 100 entries)
- Starts background goroutine for cache cleanup every 24 hours
At Runtime (after core validation passes):
- Scans
messagefield for objects with@contextand@type - Skips core Beckn schemas (containing
/schema/core/) - Downloads domain schemas from
@contextURLs (cached for 24 hours) - Validates domain-specific data against schemas
- Returns errors with full JSON paths (e.g.,
message.order.chargingRate) - Fail-fast: returns on first validation error
Dependencies
github.com/getkin/kin-openapi- OpenAPI 3 parser and validator
Error Messages
| Scenario | Error Message |
|---|---|
| Action is number | "failed to parse JSON payload: json: cannot unmarshal number into Go struct field .context.action of type string" |
| Action is empty | "missing field Action in context" |
| Action not in spec | "unsupported action: <action>" |
| Invalid URL | "Invalid URL or unreachable: <url>" |
| Schema validation fails | Returns detailed field-level errors |