Expand description
Derive complete REST APIs from Sea-ORM entities.
crudcrate generates CRUD endpoints, request/response models, filtering, sorting,
pagination, batch operations, relationship loading, and OpenAPI schemas from a single
#[derive(EntityToModels)] on your Sea-ORM model. It targets Axum
and uses utoipa for schema generation.
For tutorials, walkthroughs, and guides see https://crudcrate.evanjt.com.
§Quick start
use chrono::{DateTime, Utc};
use crudcrate::EntityToModels;
use sea_orm::entity::prelude::*;
use uuid::Uuid;
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, EntityToModels)]
#[sea_orm(table_name = "todos")]
#[crudcrate(api_struct = "Todo", generate_router)]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
#[crudcrate(primary_key, exclude(create, update), on_create = Uuid::new_v4())]
pub id: Uuid,
#[crudcrate(filterable, sortable, fulltext)]
pub title: String,
#[crudcrate(sortable, exclude(create, update), on_create = Utc::now())]
pub created_at: DateTime<Utc>,
}This generates:
Todo,TodoCreate,TodoUpdate,TodoListstructs- A
CRUDResourceimplementation with default get/create/update/delete logic Todo::router(&db)returning an AxumRouterwith all endpoints
Mount it:
let app = Router::new().nest("/todos", Todo::router(&db));§Generated endpoints
| Method | Path | Description |
|---|---|---|
| GET | /{resource} | List with filtering, sorting, fulltext search, pagination |
| GET | /{resource}/{id} | Single item with optional relationship loading |
| POST | /{resource} | Create |
| PUT | /{resource}/{id} | Partial update |
| DELETE | /{resource}/{id} | Delete |
| POST | /{resource}/batch | Batch create |
| PATCH | /{resource}/batch | Batch update |
| DELETE | /{resource}/batch | Batch delete |
§Filtering and search
Fields marked filterable accept query parameters with operator suffixes:
GET /todos?filter={"completed":false,"priority_gte":3}
GET /todos?q=urgent review # fulltext search
GET /todos?sort=["created_at","DESC"]
GET /todos?range=[0,24] # pagination (React Admin compatible)See the filtering module for the full operator reference.
§Relationship loading
Non-database fields annotated with join(...) are populated automatically:
#[sea_orm(ignore)]
#[crudcrate(non_db_attr, join(one, all, depth = 2))]
pub vehicles: Vec<Vehicle>,At depth 1, list endpoints use batch loading (2 queries, not N+1). Recursive loading supports up to depth 5. Self-referencing fields are constrained to depth 1 at compile time.
§Hooks
Override any phase of any operation with attribute-based hooks:
#[crudcrate(
generate_router,
create::one::pre = validate_input,
read::one::transform = enrich_with_metadata,
delete::one::post = cleanup_s3_assets,
)]Hook phases run in order: pre → body → transform → post.
See the EntityToModels derive macro docs for the full attribute reference,
and the operations module for the CRUDOperations trait (an alternative
to per-attribute hooks).
§Modules
core—CRUDResourcetrait, default CRUD implementationsfiltering— Query parameter parsing, filter conditions, pagination, sorting, fulltext searchoperations—CRUDOperationstrait for struct-based customizationerrors—ApiErrortype with automatic HTTP status codes and internal loggingdatabase— Index analysis utilitiesvalidation— Input validation helpers
§Feature flags
| Flag | Default | Description |
|---|---|---|
derive | yes | Enables procedural macros (EntityToModels, etc.) |
sqlite | yes | SQLite support via sqlx |
postgresql | no | PostgreSQL support (enables GIN/tsvector fulltext) |
mysql | no | MySQL support (enables FULLTEXT indexes) |
spring-rs | no | Spring-RS framework integration |
Re-exports§
pub use core::CRUDResource;pub use core::MergeIntoActiveModel;pub use core::UuidIdResult;pub use errors::ApiError;pub use errors::BatchFailure;pub use errors::BatchResult;pub use filtering::BatchOptions;pub use filtering::FilterOperator;pub use filtering::FilterOptions;pub use filtering::JoinedColumnDef;pub use filtering::JoinedFilter;pub use filtering::ParsedFilters;pub use filtering::SortConfig;pub use filtering::apply_filters;pub use filtering::apply_filters_with_joins;pub use filtering::calculate_content_range;pub use filtering::parse_dot_notation;pub use filtering::parse_pagination;pub use filtering::parse_range;pub use filtering::parse_sorting;pub use filtering::parse_sorting_with_joins;pub use operations::CRUDOperations;pub use operations::DefaultCRUDOperations;pub use scope::ScopeCondition;pub use scope::ScopeFilterable;pub use serde_with;
Modules§
- core
- Auto-Generated CRUD Operations
- database
- errors
- Error types for CRUD handlers.
- filtering
- Filtering, sorting, pagination, and fulltext search.
- operations
- Trait-based CRUD customization.
- relationships
- scope
- validation
- Validation Support
Macros§
- crud_
handlers - crud_
handlers_ impl - generate_
crud_ router - impls
- Returns
trueif a type implements a logical trait expression.
Derive Macros§
- Entity
ToModels - Generates complete CRUD API structures from Sea-ORM entities.
- ToCreate
Model - Generates
<Name>Createstruct with fields not excluded byexclude(create). Fields withon_createbecomeOption<T>to allow user override. ImplementsFrom<NameCreate>forActiveModelwith automatic value generation. - ToList
Model - Generates
<Name>Liststruct with fields not excluded byexclude(list). Optimizes API payloads by excluding heavy fields (joins, large text) from list endpoints. ImplementsFrom<Name>andFrom<Model>conversions. - ToUpdate
Model - Generates
<Name>Updatestruct with fields not excluded byexclude(update). All fields areOption<Option<T>>to support partial updates and explicit null. ImplementsMergeIntoActiveModeltrait withon_updateexpression handling.