Overview
Creates a new document in the specified collection. The endpoint automatically:
- Validates the document against the collection schema
- Populates
created_at, updated_at, created_by fields
- Applies tenant isolation if configured
- Executes pre/post-create hooks
- Enforces RBAC permissions
- Logs the operation to audit trail
Request
Path Parameters
The name of the collection to create the document in
Bearer token for authentication
Body
The request body should contain a JSON object representing the document to create. All fields will be validated against the collection’s schema.
Custom fields as defined in your collection schema. The system automatically adds:
created_at (timestamp)
updated_at (timestamp)
created_by (user ID from auth context)
- Tenant/owner fields if configured in the collection’s access settings
Response
The unique identifier of the newly created document
ISO 8601 timestamp when the document was created
ISO 8601 timestamp when the document was last updated
User ID of the user who created the document
All other fields from your request body, filtered by field-level permissions
Examples
Basic Create
curl -X POST https://api.example.com/users \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "[email protected]",
"role": "member"
}'
Response
{
"_id": "507f1f77bcf86cd799439011",
"name": "John Doe",
"email": "[email protected]",
"role": "member",
"created_at": "2024-03-15T10:30:00Z",
"updated_at": "2024-03-15T10:30:00Z",
"created_by": "user_123",
"company_id": "company_456"
}
Implementation Details
MongoDB Query Pattern
The handler uses MongoDB’s insertOne operation:
result, err := collection.InsertOne(ctx, doc)
if err != nil {
return err
}
id := result.InsertedID
Workflow
- Extract collection name from URL path (handlers_crud.go:67)
- Authenticate request and extract auth context (handlers_crud.go:74)
- Validate collection exists in schema config (handlers_crud.go:81)
- Check RBAC permissions for create action (handlers_crud.go:90)
- Parse JSON body and validate structure (handlers_crud.go:99)
- Auto-populate fields:
created_by, created_at, updated_at (handlers_crud.go:108-111)
- Tenant field (e.g.,
company_id) from auth context (handlers_crud.go:114)
- Owner field if configured (handlers_crud.go:117)
- Validate against schema using validator (handlers_crud.go:122)
- Execute pre-create hooks if configured (handlers_crud.go:134)
- Insert into MongoDB using store.Create (handlers_crud.go:155)
- Execute post-create hooks (best-effort) (handlers_crud.go:168)
- Log audit event with success/failure (handlers_crud.go:183)
- Apply field policy to filter response fields (handlers_crud.go:186)
- Return 201 Created with document (handlers_crud.go:189)
Automatic Field Population
now := time.Now().UTC()
doc["created_by"] = authCtx.UserID
doc["created_at"] = now
doc["updated_at"] = now
// Set tenant/company_id from auth if configured
if collConfig.Access.TenantField != "" {
doc[collConfig.Access.TenantField] = authCtx.TenantID
}
if collConfig.Access.OwnerField != "" {
doc[collConfig.Access.OwnerField] = authCtx.UserID
}
Error Responses
400 Bad Request
Returned when:
- Collection name is missing
- Invalid JSON body
- Schema validation fails
- Pre-create hook fails
{
"error": "Validation failed",
"code": "schema_validation",
"details": {
"validation_errors": [
{
"field": "email",
"code": "invalid_format",
"message": "Invalid email format"
}
]
}
}
401 Unauthorized
{
"error": "Authentication required"
}
403 Forbidden
Returned when user doesn’t have create permission:
{
"error": "You don't have permission to perform this action",
"code": "forbidden",
"details": {
"action": "create",
"collection": "users"
}
}
404 Not Found
Returned when collection doesn’t exist in schema:
{
"error": "Collection not found",
"code": "collection_not_found",
"details": {
"collection": "invalid_collection"
}
}
500 Internal Server Error
{
"error": "Failed to create document",
"code": "internal_error",
"details": {
"error": "database connection failed"
}
}
Hooks
You can intercept the create operation using hooks:
Pre-Create Hook
Executed before the document is inserted. Can modify the document or reject the operation:
function preCreate(event) {
// event.after contains the document to be created
// Modify or validate the document
event.after.slug = event.after.name.toLowerCase().replace(/\s+/g, '-');
return event;
}
Post-Create Hook
Executed after successful creation (best-effort, won’t fail the request):
function postCreate(event) {
// event.after contains the created document with _id
// Trigger side effects like notifications
sendWelcomeEmail(event.after.email);
}