Extensions
Extensions
Section titled “Extensions”Extension mechanism for optional capabilities
Overview
Section titled “Overview”Extensions add optional capabilities to Mesh 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": "mesh", "version": "0.1.0" }, "id": "req_123", "call": { "function": "reports.generate", "version": "1", "arguments": { "type": "quarterly" } }, "extensions": [ { "urn": "urn:mesh: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": "mesh", "version": "0.1.0" }, "id": "req_123", "result": { "queued": true }, "meta": { "duration": { "value": 45, "unit": "millisecond" } }, "extensions": [ { "urn": "urn:mesh:ext:async", "data": { "operation_id": "op_xyz789", "status": "processing", "poll": { "function": "mesh.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:
urn:mesh:ext:asyncurn:mesh:ext:example:auditRules:
- MUST be a valid URN
- 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": "mesh", "version": "0.1.0" }, "id": "req_123", "result": null, "errors": [{ "code": "EXTENSION_NOT_SUPPORTED", "message": "Extension not supported: urn:mesh:ext:example:unknown", "retryable": false, "details": { "unsupported": ["urn:mesh:ext:example:unknown"], "supported": ["urn:mesh:ext:async"] } }]}Unknown Extensions
Section titled “Unknown Extensions”Servers MUST ignore extension objects with unrecognized URIs if the request does not require them.
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:mesh: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:mesh:ext:async | Long-running operations with polling/callbacks |
| Batch | urn:mesh:ext:batch | Multiple operations in a single request |
| Caching | urn:mesh:ext:caching | ETags, cache hints, conditional requests |
| Deadline | urn:mesh:ext:deadline | Request timeouts to prevent cascading failures |
| Deprecation | urn:mesh:ext:deprecation | Warnings for deprecated functions/versions |
| Dry Run | urn:mesh:ext:dry-run | Validate operations without executing |
| Idempotency | urn:mesh:ext:idempotency | Request deduplication for safe retries |
| Priority | urn:mesh:ext:priority | Request priority hints for queue management |
| Quota | urn:mesh:ext:quota | Usage quotas and limits information |
| Tracing | urn:mesh:ext:tracing | Distributed tracing for observability |
Extension Discovery
Section titled “Extension Discovery”Clients MAY discover supported extensions:
// Request{ "protocol": { "name": "mesh", "version": "0.1.0" }, "id": "req_discover", "call": { "function": "mesh.capabilities", "version": "1", "arguments": {} }}
// Response{ "protocol": { "name": "mesh", "version": "0.1.0" }, "id": "req_discover", "result": { "protocol_versions": ["0.1.0"], "extensions": [ { "urn": "urn:mesh:ext:async", "documentation": "urn:mesh:ext:async" } ] }}See System Functions for details.
Examples
Section titled “Examples”Request with Extension
Section titled “Request with Extension”{ "protocol": { "name": "mesh", "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:mesh: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": "mesh", "version": "0.1.0" }, "id": "req_ext", "result": { "deleted": true }, "meta": { "duration": { "value": 45, "unit": "millisecond" } }, "extensions": [ { "urn": "urn:mesh:ext:audit", "data": { "log_id": "audit_log_789", "logged_at": "2024-03-15T14:30:00Z" } } ]}Multiple Extensions
Section titled “Multiple Extensions”{ "protocol": { "name": "mesh", "version": "0.1.0" }, "id": "req_multi", "call": { "function": "reports.generate", "version": "1", "arguments": { "type": "quarterly" } }, "extensions": [ { "urn": "urn:mesh:ext:audit", "options": { "actor": { "user_id": "admin_1" } } }, { "urn": "urn:mesh:ext:async", "options": { "preferred": true } } ]}Multiple Extensions Response
Section titled “Multiple Extensions Response”{ "protocol": { "name": "mesh", "version": "0.1.0" }, "id": "req_multi", "result": null, "meta": { "duration": { "value": 12, "unit": "millisecond" } }, "extensions": [ { "urn": "urn:mesh:ext:audit", "data": { "log_id": "audit_log_790" } }, { "urn": "urn:mesh:ext:async", "data": { "operation_id": "op_abc123", "status": "processing", "poll": { "function": "mesh.operation.status", "version": "1", "arguments": { "operation_id": "op_abc123" } }, "retry_after": { "value": 5, "unit": "second" } } } ]}