Skip to main content

Crate crudcrate

Crate crudcrate 

Source
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, TodoList structs
  • A CRUDResource implementation with default get/create/update/delete logic
  • Todo::router(&db) returning an Axum Router with all endpoints

Mount it:

let app = Router::new().nest("/todos", Todo::router(&db));

§Generated endpoints

MethodPathDescription
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}/batchBatch create
PATCH/{resource}/batchBatch update
DELETE/{resource}/batchBatch delete

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: prebodytransformpost.

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

§Feature flags

FlagDefaultDescription
deriveyesEnables procedural macros (EntityToModels, etc.)
sqliteyesSQLite support via sqlx
postgresqlnoPostgreSQL support (enables GIN/tsvector fulltext)
mysqlnoMySQL support (enables FULLTEXT indexes)
spring-rsnoSpring-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 true if a type implements a logical trait expression.

Derive Macros§

EntityToModels
Generates complete CRUD API structures from Sea-ORM entities.
ToCreateModel
Generates <Name>Create struct with fields not excluded by exclude(create). Fields with on_create become Option<T> to allow user override. Implements From<NameCreate> for ActiveModel with automatic value generation.
ToListModel
Generates <Name>List struct with fields not excluded by exclude(list). Optimizes API payloads by excluding heavy fields (joins, large text) from list endpoints. Implements From<Name> and From<Model> conversions.
ToUpdateModel
Generates <Name>Update struct with fields not excluded by exclude(update). All fields are Option<Option<T>> to support partial updates and explicit null. Implements MergeIntoActiveModel trait with on_update expression handling.