CRUD Operations
CRUD Operations When you create a table in Enfyra (e.g. products, orders, customers), it automatically gets REST endpoints. Use them from your app to list, create, update, and delete records. Base: {appUrl}/api/{routePath} The route path matches your table name or custom route (e
CRUD Operations
When you create a table in Enfyra (e.g. products, orders, customers), it automatically gets REST endpoints. Use them from your app to list, create, update, and delete records.
Base: {appUrl}/api/{routePath}
The route path matches your table name or custom route (e.g. /products, /orders). Check your Enfyra Collections to see available routes.
GET /{routePath}
List records with optional filtering, sorting, and pagination.
URL: {appUrl}/api/{routePath}
Query Parameters: See Query Parameters.
Example:
curl "http://localhost:3000/api/products?limit=10&fields=id,name,price" \
-H "Authorization: Bearer YOUR_TOKEN"
Response (200):
{
"statusCode": 200,
"message": "Success",
"data": [
{ "id": 1, "email": "[email protected]", "name": "User 1" },
{ "id": 2, "email": "[email protected]", "name": "User 2" }
],
"meta": {
"totalCount": 50,
"filterCount": 2
}
}
Get One Record
Dynamic REST routes do not expose GET /{routePath}/:id. Fetch a single record by using the list endpoint with a primary-key filter and limit=1.
URL: {appUrl}/api/{routePath}?filter={"id":{"_eq":1}}&limit=1
Example:
curl 'http://localhost:3000/api/user_definition?filter={"id":{"_eq":1}}&limit=1' \
-H "Authorization: Bearer YOUR_TOKEN"
Response (200):
{
"statusCode": 200,
"message": "Success",
"data": [
{
"id": 1,
"email": "[email protected]",
"name": "User 1",
"role": { "id": 1, "name": "Admin" }
}
]
}
Read the first item from data. For MongoDB, use _id instead of id if your schema uses it.
POST /{routePath}
Create a new record.
URL: {appUrl}/api/{routePath}
Request Body: JSON object with the table's fields.
Example:
curl -X POST "http://localhost:3000/api/user_definition" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","name":"New User","password":"secret123"}'
Response (200):
{
"statusCode": 200,
"message": "Success",
"data": [
{
"id": 3,
"email": "[email protected]",
"name": "New User",
"createdAt": "2024-01-15T12:00:00.000Z"
}
]
}
PATCH /{routePath}/:id
Update an existing record.
URL: {appUrl}/api/{routePath}/{id}
Request Body: JSON object with fields to update (partial update).
Example:
curl -X PATCH "http://localhost:3000/api/user_definition/3" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Updated Name"}'
Response (200): The default update handler returns a collection-shaped result with the updated record in data[0].
DELETE /{routePath}/:id
Delete a record.
URL: {appUrl}/api/{routePath}/{id}
Example:
curl -X DELETE "http://localhost:3000/api/user_definition/3" \
-H "Authorization: Bearer YOUR_TOKEN"
Response (200): The default delete handler returns { "message": "Success", "statusCode": 200 }.
Body Validation (POST / PATCH)
If the table has validateBody = true (default for new tables), the server validates the request body against the table's schema and any column rules attached to its columns. Validation runs before the handler executes.
What is checked, in order:
- Column type (int, varchar, boolean, etc.)
- Nullability (
isNullable: falsecolumns rejectnull) - Length cap for
varchar(options.length) - Column rules (min/max, minLength/maxLength, pattern, format, minItems/maxItems)
- Strictness — unknown top-level fields are rejected
Failure response (HTTP 400):
{
"statusCode": 400,
"message": [
"name: String must contain at least 3 character(s)",
"email: Invalid email",
"age: Number must be greater than or equal to 18"
],
"error": "Bad Request"
}
message is always an array of strings — one per violation. The prefix before : is the field name; clients can split on : to map errors back to form fields.
Notes:
- Cascade create payloads (e.g.
POST /postwith inlinecomments: [...]) validate child records too if the related table also hasvalidateBody = true. - Connect-by-id shapes (
{ author: 5 }or{ author: { id: 5 } }) skip nested validation. - Tables with
validateBody = falseonly enforce database-level constraints at insert/update time; rules are not consulted. - Field-permission
denyoncreate/updatereturns 403, not 400 — that's not validation.
To configure rules per column, see the admin app guide: Column Rules.
Custom Routes
You can add custom routes (e.g. /register, /orders/:orderId/items) in Enfyra Settings. Each route exposes the HTTP methods configured for it. Use the same base URL and authentication as for table routes.