directus-extension-query-collection-endpoint
v1.0.1
Published
Execute SQL queries stored in Directus collections via GET endpoints
Maintainers
Readme
Directus Query Collection Endpoint
Execute SQL queries stored in Directus collections via GET endpoints.
Features
- Execute SQL queries stored in any Directus collection
- Schema-agnostic: works with any collection structure
- Support for query parameters via URL query string
- Directus access policies for permission control
- Status-based publishing control (
status = published) - Automatic primary key detection
Installation
# npm
npm install
npm run build
# pnpm
pnpm install
pnpm run build
# yarn
yarn install
yarn run buildCopy the built extension to Directus:
cp -r dist /path/to/directus/extensions/directus-query-collection-endpointAPI Endpoint
GET /query-collection/execute/:collection/:primaryKey/:sqlField
Execute a SQL query stored in a Directus collection.
Parameters:
collection: Name of the Directus collection containing the queryprimaryKey: Value of the primary key to find the recordsqlField: Name of the field containing the SQL query- Query params: Optional parameters for SQL query substitution
Examples:
Example 1: Simple query
GET /query-collection/execute/queries/123/sql
# Finds record in 'queries' collection with id=123
# Executes SQL from the 'sql' fieldExample 2: Query with parameters
GET /query-collection/execute/reports/monthly-sales/query?startDate=2026-01-01&endDate=2026-01-31
# SQL in database uses named parameters:
# SELECT * FROM sales WHERE created_at BETWEEN :startDate AND :endDateUsage Guide
1. Create a collection for storing queries
In Directus, create a collection (e.g., saved_queries) with fields:
id(integer, primary key)name(string) - descriptive namesql(text) - the SQL querystatus(string, optional) - only records withpublishedstatus are executable
2. Add a query record
{
"id": 1,
"name": "Get active users",
"sql": "SELECT * FROM directus_users WHERE status = :status LIMIT :limit",
"status": "published"
}3. Execute the query
curl -H "Authorization: Bearer YOUR_TOKEN" \
"http://localhost:8055/query-collection/execute/saved_queries/1/sql?status=active&limit=10"Response:
{
"success": true,
"data": [
{ "id": 1, "email": "[email protected]", "status": "active" },
{ "id": 2, "email": "[email protected]", "status": "active" }
],
"rowCount": 2,
"executedAt": "2026-02-05T10:30:00.000Z"
}Security
Multi-level security model
Level 1: Directus access policies (automatic)
- Uses Directus native access policies and permissions
- If user can't read the collection, they can't execute queries
- Enforced automatically via
ItemsServicewithaccountability
Level 2: Status check (automatic)
- If the record has a
statusfield, only records withstatus = "published"can be executed - Unpublished, draft, or archived queries return a 404 error
Level 3: SQL parameter binding
- All parameters use Knex named parameter binding (
:paramName) - Prevents SQL injection attacks
- Parameters can only replace values, not table/column names
SQL Parameter Syntax
Use named parameters in your SQL queries:
-- Named parameters with colon prefix
SELECT * FROM users
WHERE status = :status
AND created_at > :startDate
AND role IN (:role1, :role2)
LIMIT :limitCall the endpoint with query parameters:
?status=active&startDate=2026-01-01&role1=admin&role2=editor&limit=50Type Coercion
Query parameters are automatically converted:
"true"/"false"→ boolean- Numeric strings → numbers
- Everything else → strings
Error Responses
| Status | Description | | ------ | -------------------------------------------------- | | 400 | Bad request (missing parameters) | | 401 | Unauthorized (not authenticated) | | 403 | Forbidden (insufficient permissions) | | 404 | Not found (collection/record/field doesn't exist) | | 500 | Internal server error (SQL execution failed) |
Example error:
{
"success": false,
"error": "This query is not published"
}Development
# Install dependencies
npm install # or pnpm install / yarn install
# Development mode with watch
npm run dev # or pnpm run dev / yarn run dev
# Build for production
npm run build # or pnpm run build / yarn run build
# Link to local Directus instance
npm run link # or pnpm run link / yarn run linkTesting
Create a test collection in Directus:
- Name:
test_queries - Fields:
id(PK),name(string),sql(text),status(string)
- Name:
Add a test query:
{ "id": 1, "name": "Test query", "sql": "SELECT * FROM directus_users LIMIT :limit", "status": "published" }Test the endpoint:
curl -H "Authorization: Bearer YOUR_TOKEN" \ "http://localhost:8055/query-collection/execute/test_queries/1/sql?limit=5"
Advantages
- Reusability: Store queries once, execute many times
- Version control: Leverage Directus revision system
- RESTful: Simple GET requests with query parameters
- Directus permissions: Uses native access policies
- Publishing workflow: Only published queries are executable
- Schema-agnostic: Works with any collection structure
- Type-safe parameters: Automatic type coercion
- SQL injection protection: Knex named parameter binding
Requirements
- Directus >= 11.0.0
- Node >= 18.x.x
- npm >= 8.0.0 / pnpm >= 8.0.0 / yarn >= 1.22.0
License
MIT
