ObjectQL
ReferenceAPI Reference

JSON-RPC Style API

JSON-RPC Style API

The primary ObjectQL API is a JSON-RPC style protocol where all operations are sent to a single endpoint.

Base Endpoint

POST /api/objectql
Content-Type: application/json

Request Format

interface ObjectQLRequest {
  // Authentication context (optional, can also come from headers)
  user?: {
    id: string;
    roles: string[];
    [key: string]: any;
  };
  
  // The operation to perform
  op: 'find' | 'findOne' | 'create' | 'update' | 'delete' | 'count' | 'action' | 'createMany' | 'updateMany' | 'deleteMany';
  
  // The target object/table
  object: string;
  
  // Operation-specific arguments
  args: any;
}

Response Format

interface ObjectQLResponse {
  // For list operations (find)
  items?: any[];
  
  // Pagination metadata (for list operations)
  meta?: {
    total: number;      // Total number of records
    page?: number;      // Current page number (1-indexed)
    size?: number;      // Number of items per page
    pages?: number;     // Total number of pages
    has_next?: boolean; // Whether there is a next page
  };
  
  // For single item operations, the response is the object itself with '@type' field
  // Examples: findOne, create, update return { id: '...', name: '...', '@type': 'users' }
  '@type'?: string;    // Object type identifier
  
  // Error information
  error?: {
    code: string;
    message: string;
    details?: any;
  };
  
  // Other fields from the actual data object (for single item responses)
  [key: string]: any;
}

Operations

1. find - Query Records

Retrieve multiple records with filtering, sorting, pagination, and joins.

Request:

{
  "op": "find",
  "object": "orders",
  "args": {
    "fields": ["order_no", "amount", "status", "created_at"],
    "filters": [
      ["status", "=", "paid"],
      "and",
      ["amount", ">", 1000]
    ],
    "sort": [["created_at", "desc"]],
    "top": 20,
    "skip": 0,
    "expand": {
      "customer": {
        "fields": ["name", "email"]
      }
    }
  }
}

Response:

{
  "items": [
    {
      "order_no": "ORD-001",
      "amount": 1500,
      "status": "paid",
      "created_at": "2024-01-15T10:30:00Z",
      "customer": {
        "name": "Acme Corp",
        "email": "contact@acme.com"
      }
    }
  ],
  "meta": {
    "total": 150,
    "page": 1,
    "size": 20,
    "pages": 8,
    "has_next": true
  }
}

2. findOne - Get Single Record

Retrieve a single record by ID or query.

Request (by ID):

{
  "op": "findOne",
  "object": "users",
  "args": "user_123"
}

Request (by query):

{
  "op": "findOne",
  "object": "users",
  "args": {
    "filters": [["email", "=", "alice@example.com"]]
  }
}

Response:

{
  "id": "user_123",
  "name": "Alice",
  "email": "alice@example.com",
  "@type": "users"
}

3. create - Create Record

Insert a new record.

Request:

{
  "op": "create",
  "object": "tasks",
  "args": {
    "name": "Review PR",
    "priority": "high",
    "assignee_id": "user_123",
    "due_date": "2024-01-20"
  }
}

Response:

{
  "id": "task_456",
  "name": "Review PR",
  "priority": "high",
  "assignee_id": "user_123",
  "due_date": "2024-01-20",
  "created_at": "2024-01-15T10:30:00Z",
  "@type": "tasks"
}

4. update - Update Record

Modify an existing record.

Request:

{
  "op": "update",
  "object": "tasks",
  "args": {
    "id": "task_456",
    "data": {
      "status": "completed",
      "completed_at": "2024-01-16T14:00:00Z"
    }
  }
}

Response:

{
  "id": "task_456",
  "status": "completed",
  "completed_at": "2024-01-16T14:00:00Z",
  "@type": "tasks"
}

5. delete - Delete Record

Remove a record by ID.

Request:

{
  "op": "delete",
  "object": "tasks",
  "args": {
    "id": "task_456"
  }
}

Response:

{
  "id": "task_456",
  "deleted": true,
  "@type": "tasks"
}

6. count - Count Records

Get the count of records matching a filter.

Request:

{
  "op": "count",
  "object": "orders",
  "args": {
    "filters": [
      ["status", "=", "pending"]
    ]
  }
}

Response:

{
  "count": 42,
  "@type": "orders"
}

7. action - Execute Custom Action

Execute a custom server-side action (RPC-style operation).

Request:

{
  "op": "action",
  "object": "orders",
  "args": {
    "action": "approve",
    "id": "order_789",
    "input": {
      "approved_by": "manager_123",
      "notes": "Approved for expedited shipping"
    }
  }
}

Response:

{
  "success": true,
  "message": "Order approved successfully",
  "order": {
    "id": "order_789",
    "status": "approved",
    "approved_at": "2024-01-15T10:30:00Z"
  },
  "@type": "orders"
}

Bulk Operations

ObjectQL supports efficient bulk operations for creating, updating, and deleting multiple records in a single request.

Important Notes:

  • Validation & Hooks: Bulk operations process each record individually to ensure validation rules and hooks (beforeCreate, afterCreate, etc.) are properly executed, maintaining data integrity
  • Atomicity: Operations are not atomic by default - if one record fails, others may have already been processed
  • Performance: While bulk operations are more efficient than separate API calls, they may be slower than driver-level bulk operations due to individual validation/hook execution
  • Use Cases: Use bulk operations when you need consistent validation and business logic enforcement. For high-performance batch imports where validation is already handled, consider using driver-level operations directly

8. createMany - Create Multiple Records

Insert multiple records in a single operation.

Request:

{
  "op": "createMany",
  "object": "tasks",
  "args": [
    {
      "name": "Task 1",
      "priority": "high",
      "assignee_id": "user_123"
    },
    {
      "name": "Task 2",
      "priority": "medium",
      "assignee_id": "user_456"
    },
    {
      "name": "Task 3",
      "priority": "low",
      "assignee_id": "user_789"
    }
  ]
}

Response:

{
  "items": [
    {
      "id": "task_101",
      "name": "Task 1",
      "priority": "high",
      "assignee_id": "user_123",
      "created_at": "2024-01-15T10:30:00Z"
    },
    {
      "id": "task_102",
      "name": "Task 2",
      "priority": "medium",
      "assignee_id": "user_456",
      "created_at": "2024-01-15T10:30:00Z"
    },
    {
      "id": "task_103",
      "name": "Task 3",
      "priority": "low",
      "assignee_id": "user_789",
      "created_at": "2024-01-15T10:30:00Z"
    }
  ],
  "count": 3,
  "@type": "tasks"
}

9. updateMany - Update Multiple Records

Update all records matching a filter.

Request:

{
  "op": "updateMany",
  "object": "tasks",
  "args": {
    "filters": {
      "status": "pending",
      "priority": "low"
    },
    "data": {
      "status": "cancelled",
      "cancelled_at": "2024-01-15T10:30:00Z"
    }
  }
}

Response:

{
  "count": 15,
  "@type": "tasks"
}

10. deleteMany - Delete Multiple Records

Delete all records matching a filter.

Request:

{
  "op": "deleteMany",
  "object": "tasks",
  "args": {
    "filters": {
      "status": "completed",
      "completed_at": ["<", "2023-01-01"]
    }
  }
}

Response:

{
  "count": 42,
  "@type": "tasks"
}

Error Handling Example:

// If a record fails validation during bulk operation
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "fields": {
        "priority": "Invalid priority value"
      }
    }
  }
}

Advanced Query Features

AI Context (Optional)

Add semantic information to queries for better logging, debugging, and AI processing:

{
  "op": "find",
  "object": "projects",
  "ai_context": {
    "intent": "Find at-risk projects requiring immediate attention",
    "natural_language": "Show active projects that are overdue or over budget",
    "use_case": "Project manager dashboard"
  },
  "args": {
    "filters": [
      ["status", "=", "active"],
      "and",
      [
        ["end_date", "<", "$today"],
        "or",
        ["actual_cost", ">", "budget"]
      ]
    ]
  }
}

Aggregation Queries

Perform GROUP BY operations:

{
  "op": "find",
  "object": "orders",
  "args": {
    "groupBy": ["category"],
    "aggregate": [
      {
        "func": "sum",
        "field": "amount",
        "alias": "total_sales"
      },
      {
        "func": "count",
        "field": "id",
        "alias": "order_count"
      }
    ],
    "filters": [["status", "=", "paid"]],
    "sort": [["total_sales", "desc"]]
  }
}

On this page