crudcrate
Tired of writing boilerplate for your APIs? Frustrated that your API models look almost identical to your database models, but you have to maintain both? What if you could get a complete CRUD API running in minutes, then customize only the parts that need special handling?
crudcrate transforms your Sea-ORM entities into fully-featured REST APIs with one line of code.
use EntityToModels;
// That's it. You now have:
// - Complete CRUD endpoints (GET, POST, PUT, DELETE)
// - Auto-generated API models (Todo, TodoCreate, TodoUpdate, TodoList)
// - Filtering, sorting, and pagination
// - OpenAPI documentation
The Problem We're Solving
You've been here before:
- Write your database model -
Customerwith id, name, email, created_at - Create API response model - Basically the same as Customer, but with serde attributes
- Create request model for POST - Same as Customer, but without id and created_at
- Create update model for PUT - Same as POST, but all fields optional
- Write 6 HTTP handlers - get_all, get_one, create, update, delete, delete_many
- Wire up routes - Map each handler to an endpoint
- Add filtering logic - Parse query params, build database conditions
- Add pagination - Calculate offsets, limit results
- Add sorting - Parse sort parameters, apply to queries
- Add validation - Make sure fields are correct types
- Add error handling - Return proper HTTP status codes
- Add OpenAPI docs - Document all endpoints manually
And you repeat this for every single entity in your application.
Our Solution
Let crudcrate handle the repetitive stuff:
// Just plug it in:
let app = new
.nest;
What you get instantly:
GET /api/customers- List with filtering, sorting, paginationGET /api/customers/{id}- Get single customerPOST /api/customers- Create new customerPUT /api/customers/{id}- Update customerDELETE /api/customers/{id}- Delete customer- Auto-generated
Customer,CustomerCreate,CustomerUpdate,CustomerListmodels - Built-in filtering:
?filter={"name_like":"John"} - Built-in sorting:
?sort=name&order=DESCor?sort=["name","DESC"] - Built-in pagination:
?page=1&per_page=20or?range=[0,19](React Admin)
But What If I Need Custom Logic?
That's where crudcrate shines. You get the basics for free, but can override anything:
// Need custom validation or permissions?
async
Override any operation: fn_get_one, fn_get_all, fn_create, fn_update, fn_delete, fn_delete_many
Generated Models
One entity becomes four specialized models:
// Generated models:
Real-World Features You'll Actually Use
Smart Filtering
pub title: String,
pub priority: i32,
Your users can now:
# Exact matches
# Numeric ranges
# Text search across all searchable fields
# Combine filters
Relationship Loading
Automatically load related data in API responses with full recursive support:
Multi-level recursive loading works out of the box:
- Customer → Vehicles → Parts/Maintenance Records (3 levels deep)
- No complex SQL joins required - uses efficient recursive queries
- Automatic cycle detection prevents infinite recursion
Join options:
join(one)- Load only in individual item responsesjoin(all)- Load only in list responsesjoin(one, all)- Load in both types of responsesjoin(one, all, depth = 2)- Custom depth guidance (default: unlimited)
Field Control
Sometimes certain fields shouldn't be in certain models:
// Password hash: never send to clients, never allow updates
pub password_hash: String,
// API keys: generate server-side, never expose in any response
pub api_key: String,
// Internal notes: exclude from list (expensive) but show in detail view
pub internal_notes: String,
// Timestamps: manage automatically
pub updated_at: ,
Exclusion options:
exclude(one)- Exclude from get_one responses (main API response)exclude(create)- Exclude from POST request modelsexclude(update)- Exclude from PUT request modelsexclude(list)- Exclude from list responsesexclude(one, list)- Exclude from both individual and list responsesexclude(create, update)- Exclude from both request models
Production Ready
crudcrate isn't just a toy - it's built for real applications:
Database Optimizations
// Get performance recommendations for production
analyse_all_registered_models.await;
Output:
HIGH Priority:
customers - Fulltext search on name/email without proper index
CREATE INDEX idx_customers_fulltext ON customers USING GIN (to_tsvector('english', name || ' ' || email));
MEDIUM Priority:
customers - Field 'email' is filterable but not indexed
CREATE INDEX idx_customers_email ON customers (email);
Multi-Database Support
- PostgreSQL: Full GIN index support, tsvector optimization
- MySQL: FULLTEXT indexes, MATCH AGAINST queries
- SQLite: LIKE-based fallback (perfect for development)
Battle-Tested Features
- SQL injection prevention via Sea-ORM parameterization
- Input validation and sanitization
- Type-safe compile-time checks
- Comprehensive test suite across all supported databases
Security
crudcrate includes several built-in security limits to protect your application from common attack vectors.
Batch Operation Limits
Default: 100 items per batch delete
The default delete_many implementation limits batch deletions to 100 items to prevent DoS attacks via resource exhaustion.
To increase this limit, provide a custom implementation:
async
Join Depth Limits
Default: Maximum depth of 5
Recursive joins are automatically capped at depth 5 to prevent:
- Infinite recursion with circular references
- Exponential database query growth (N+1 problem)
- Database connection pool exhaustion
// Shallow joins - load one level only
pub users:
// Medium depth - 3 levels
pub organization:
// Maximum depth - defaults to 5 if unspecified
// depth = 5
pub vehicles:
// Values > 5 are automatically capped to 5
// Will be capped to 5
Compile-time warnings: If you specify depth > 5, you'll get a compile-time error informing you of the cap.
See SECURITY_AUDIT.md for complete security details.
Quick Start
use Router;
use EntityToModels;
use *;
async
That's it. You have a complete, production-ready CRUD API.
Run it:
Test it:
# Create a task
# List all tasks
# Get a specific task
# Update a task
When to Use crudcrate
Perfect for:
- Quick prototypes and MVPs
- Admin panels and internal tools
- Standard CRUD operations
- APIs that follow REST conventions
- Teams that want to move fast
Maybe not for:
- Highly specialized endpoints
- GraphQL APIs (though you could use the generated models)
- Complex business logic that doesn't fit CRUD patterns
- When you need full control over every detail
Examples
# Minimal todo API
# Relationship loading demo
License
MIT License. See LICENSE for details.