Extensions
Extensions
Section titled “Extensions”Extension mechanism for optional capabilities
Overview
Section titled “Overview”Extensions add optional capabilities to Vend without modifying the core protocol. They enable experimentation and domain-specific features while maintaining interoperability.
Extension Principles
Section titled “Extension Principles”- Explicit — Extensions MUST be declared in the request
- Contained — Extension data MUST be within the extension object
- Additive — Extensions MUST only add, not modify core behavior
- Negotiated — Both client and server MUST support the extension
Extension Structure
Section titled “Extension Structure”Request Format
Section titled “Request Format”Extensions are declared in the extensions array as objects:
{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_123", "call": { "function": "reports.generate", "version": "1", "arguments": { "type": "quarterly" } }, "extensions": [ { "urn": "urn:vnd:ext:async", "options": { "preferred": true, "callback_url": "https://my-service.example.com/webhooks" } } ]}Extension Object (Request)
Section titled “Extension Object (Request)”| Field | Type | Required | Description |
|---|---|---|---|
urn | string | Yes | Extension identifier URN |
options | object | No | Extension-specific request options |
Response Format
Section titled “Response Format”Responses mirror the request structure:
{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_123", "result": { "queued": true }, "extensions": [ { "urn": "urn:vnd:ext:tracing", "data": { "trace_id": "tr_abc123", "span_id": "span_server_001", "duration": { "value": 45, "unit": "millisecond" } } }, { "urn": "urn:vnd:ext:async", "data": { "operation_id": "op_xyz789", "status": "processing", "poll": { "function": "vend.operation.status", "version": "1", "arguments": { "operation_id": "op_xyz789" } } } } ]}Extension Object (Response)
Section titled “Extension Object (Response)”| Field | Type | Required | Description |
|---|---|---|---|
urn | string | Yes | Extension identifier URN (echoed from request) |
data | object | No | Extension-specific response data |
Extension URN
Section titled “Extension URN”Each extension is identified by a URN per RFC 8141 (Uniform Resource Names):
urn:vnd:ext:asyncurn:vnd:ext:example:auditRules:
- MUST be a valid URN per RFC 8141
- SHOULD resolve to documentation
- SHOULD use HTTPS
Server Handling
Section titled “Server Handling”Supported Extensions
Section titled “Supported Extensions”When a server supports all declared extensions:
- Process extension-specific options
- Return response with same extensions (by URN)
- Include extension-specific response data
Unsupported Extensions
Section titled “Unsupported Extensions”When a server does not support a declared extension:
{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_123", "result": null, "errors": [{ "code": "EXTENSION_NOT_SUPPORTED", "message": "Extension not supported: urn:vnd:ext:example:unknown", "retryable": false, "details": { "unsupported": ["urn:vnd:ext:example:unknown"], "supported": ["urn:vnd:ext:async"] } }]}Unknown Extensions
Section titled “Unknown Extensions”Servers MUST ignore extension objects with unrecognized URIs if the request does not require them.
Per-Function Extension Support
Section titled “Per-Function Extension Support”While vend.capabilities returns server-wide extension support, individual functions MAY restrict which extensions they accept.
When a client requests an extension that a function doesn’t support:
{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_123", "result": null, "errors": [{ "code": "EXTENSION_NOT_APPLICABLE", "message": "Caching extension not applicable to write operations", "retryable": false, "source": { "pointer": "/extensions/0" }, "details": { "extension": "urn:vnd:ext:caching", "function": "orders.create" } }]}Use vend.describe to discover which extensions a specific function supports. See System Functions for details.
Creating Extensions
Section titled “Creating Extensions”Extension Specification
Section titled “Extension Specification”An extension specification MUST define:
- URN — Unique identifier
- Options — Request options the extension accepts
- Data — Response data the extension returns
- Behavior — Processing rules
- Examples — Usage examples
Example Extension Spec
Section titled “Example Extension Spec”# Audit Extension
**URN:** urn:vnd:ext:audit
## Options (Request)
| Field | Type | Required | Description ||-------|------|----------|-------------|| `actor.user_id` | string | Yes | User performing the action || `actor.ip_address` | string | No | Client IP address || `actor.reason` | string | No | Reason for action |
## Data (Response)
| Field | Type | Description ||-------|------|-------------|| `log_id` | string | Audit log entry identifier || `logged_at` | string | ISO 8601 timestamp |
## Behavior
When the audit extension is included:1. Server MUST log the action with actor details2. Server MUST return `log_id` referencing the log entry3. Log entries MUST be immutable once createdOfficial Extensions
Section titled “Official Extensions”| Extension | URN | Description |
|---|---|---|
| Async | urn:vnd:ext:async | Long-running operations with polling/callbacks |
| Batch | urn:vnd:ext:batch | Multiple operations in a single request |
| Caching | urn:vnd:ext:caching | ETags, cache hints, conditional requests |
| Deadline | urn:vnd:ext:deadline | Request timeouts to prevent cascading failures |
| Deprecation | urn:vnd:ext:deprecation | Warnings for deprecated functions/versions |
| Dry Run | urn:vnd:ext:dry-run | Validate operations without executing |
| Idempotency | urn:vnd:ext:idempotency | Request deduplication for safe retries |
| Locale | urn:vnd:ext:locale | Internationalization and localization preferences |
| Maintenance | urn:vnd:ext:maintenance | Scheduled downtime and graceful degradation |
| Priority | urn:vnd:ext:priority | Request priority hints for queue management |
| Query | urn:vnd:ext:query | Filtering, sorting, pagination, relationships |
| Quota | urn:vnd:ext:quota | Usage quotas and limits information |
| Rate Limit | urn:vnd:ext:rate-limit | Request throttling and usage visibility |
| Redact | urn:vnd:ext:redact | Sensitive field masking and data protection |
| Replay | urn:vnd:ext:replay | Request journaling for deferred execution |
| Tracing | urn:vnd:ext:tracing | Distributed tracing for observability |
Extension Discovery
Section titled “Extension Discovery”Clients MAY discover supported extensions:
// Request{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_discover", "call": { "function": "vend.capabilities", "version": "1", "arguments": {} }}
// Response{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_discover", "result": { "protocol_versions": ["0.1.0"], "extensions": [ { "urn": "urn:vnd:ext:async", "documentation": "urn:vnd:ext:async" } ] }}See System Functions for details.
Examples
Section titled “Examples”Request with Extension
Section titled “Request with Extension”{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_ext", "call": { "function": "users.delete", "version": "1", "arguments": { "user_id": 42 } }, "context": { "trace_id": "tr_abc", "span_id": "sp_123" }, "extensions": [ { "urn": "urn:vnd:ext:audit", "options": { "actor": { "user_id": "admin_1", "ip_address": "192.168.1.1", "reason": "GDPR deletion request" } } } ]}Response with Extension
Section titled “Response with Extension”{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_ext", "result": { "deleted": true }, "extensions": [ { "urn": "urn:vnd:ext:tracing", "data": { "trace_id": "tr_abc123", "span_id": "span_server_001", "duration": { "value": 45, "unit": "millisecond" } } }, { "urn": "urn:vnd:ext:audit", "data": { "log_id": "audit_log_789", "logged_at": "2024-03-15T14:30:00Z" } } ]}Multiple Extensions
Section titled “Multiple Extensions”{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_multi", "call": { "function": "reports.generate", "version": "1", "arguments": { "type": "quarterly" } }, "extensions": [ { "urn": "urn:vnd:ext:audit", "options": { "actor": { "user_id": "admin_1" } } }, { "urn": "urn:vnd:ext:async", "options": { "preferred": true } } ]}Multiple Extensions Response
Section titled “Multiple Extensions Response”{ "protocol": { "name": "vend", "version": "0.1.0" }, "id": "req_multi", "result": null, "extensions": [ { "urn": "urn:vnd:ext:tracing", "data": { "trace_id": "tr_abc123", "span_id": "span_server_001", "duration": { "value": 12, "unit": "millisecond" } } }, { "urn": "urn:vnd:ext:audit", "data": { "log_id": "audit_log_790" } }, { "urn": "urn:vnd:ext:async", "data": { "operation_id": "op_abc123", "status": "processing", "poll": { "function": "vend.operation.status", "version": "1", "arguments": { "operation_id": "op_abc123" } }, "retry_after": { "value": 5, "unit": "second" } } } ]}