Skip to content

Latest commit

 

History

History
187 lines (147 loc) · 4.08 KB

File metadata and controls

187 lines (147 loc) · 4.08 KB

RQL Wire Protocol Specification

Version: 0.1.0

Overview

RQL (Resource Query Language) is a JSON-based protocol for querying data. This document specifies the wire format for requests and responses.

HTTP Endpoints

Endpoint Method Description
/ or /data POST Execute RQL queries
/schema GET Discover groups and ungrouped contracts
/schema/all GET Get all contracts as flat list
/schema/:groupName GET Get contracts in a specific group

Query Parameters (Schema Endpoints)

Param Default Description
pretty 0 Pretty-print JSON with indentation
raw 0 Return raw Zod schemas instead of JSON Schema

Request Format

interface RQLPayload {
  [queryKey: string]: RQLQuery;
}

interface RQLQuery {
  contract: string;           // Contract name to execute
  params?: Record<string, any>; // Input parameters
  select: RQLSelectObject;    // Fields to return
}

interface RQLSelectObject {
  [fieldName: string]: true | { select: RQLSelectObject };
}

Example Request

{
  "product": {
    "contract": "getProductDetail",
    "params": { "productId": "prod_123" },
    "select": {
      "id": true,
      "name": true,
      "manufacturer": {
        "select": { "id": true, "name": true }
      }
    }
  }
}

Response Format

interface RQLResponse {
  data: {
    [queryKey: string]: any | null;
  };
  errors: RQLResponseError[];
}

interface RQLResponseError {
  queryKey: string;
  code: RQLErrorCode;
  message: string;
  details?: unknown;
}

Example Response

{
  "data": {
    "product": {
      "id": "prod_123",
      "name": "Laptop",
      "manufacturer": { "id": "mfr_1", "name": "TechCorp" }
    }
  },
  "errors": []
}

Error Codes

Code Description
CONTRACT_NOT_FOUND Requested contract does not exist
INVALID_PARAMS Parameters failed Zod validation
INVALID_SELECT Select contains unknown/forbidden fields
INVALID_TEMPLATE Template reference is invalid or missing
CYCLE_DETECTED Circular dependency in query templates
BUDGET_EXCEEDED Query exceeds configured limits
RESOLVER_ERROR Error during resolver execution
INTERNAL_SERVER_ERROR Unexpected server error

Template Expressions

Parent Templates (Relations)

Used in relation params to reference parent object fields:

{{ parent.fieldName }}

Data Templates (Cross-Query)

Used in query params to reference completed query results:

{{ data.queryKey.fieldName }}
{{ data.queryKey.nested.path }}

Budget Limits

Default limits (configurable):

Limit Default Description
maxDepth 8 Maximum relation nesting depth
maxFields 200 Maximum fields per query
maxBatchSize 100 Maximum items in batch call
maxQueriesPerRequest 25 Maximum queries per payload

Schema Response Format

GET /schema

interface RQLSchemaResponse {
  contracts: RQLContractDefinition[]; // Ungrouped contracts
  groups: {
    name: string;
    description: string;
    contractCount: number;
  }[];
}

Contract Definition

interface RQLContractDefinition {
  name: string;
  description: string;
  type: 'GET' | 'POST' | 'UPDATE' | 'DELETE' | 'ACTION';
  params: object; // JSON Schema
  selectable: Record<string, {
    type: string;
    description: string;
    optional?: boolean;
    selectable?: Record<string, any>; // For relations
  }>;
  group?: string;
}

Relation Batching

When a relation has batch metadata:

relation: {
  contractName: "getManufacturerById",
  params: { manufacturerId: "{{ parent.manufacturerId }}" },
  batch: { param: "manufacturerId", as: "manufacturerIds" }
}

The engine will:

  1. Collect all unique manufacturerId values from parents
  2. Make a single call with { manufacturerIds: ["mfr_1", "mfr_2", ...] }
  3. Map results back to each parent

This prevents N+1 queries automatically.