WARNING: This is far from completed. Expect many breaking changes.
A declarative, resource-oriented application framework for Rust.
Define your domain model once using the resource! macro and Cinderblock generates the struct, CRUD operations, persistence layer, and REST API endpoints.
use cinderblock_core::{Context, resource, serde::{Deserialize, Serialize}};
use uuid::Uuid;
resource! {
name = Helpdesk.Support.Ticket;
attributes {
ticket_id Uuid {
primary_key true;
writable false;
default || uuid::Uuid::new_v4();
}
subject String;
status TicketStatus;
}
actions {
create open;
create assign { accept [subject]; };
update close {
accept [];
change_ref |ticket| {
ticket.status = TicketStatus::Closed;
};
};
destroy remove;
}
extensions {
cinderblock_json_api {};
cinderblock_sqlx { table = "tickets"; };
}
}This single declaration generates:
- A
Ticketstruct with serialization - Typed action markers (
Open,Assign,Close,Remove) with dedicated input structs Create,Update, andDestroytrait implementations- REST API endpoints via Axum with OpenAPI documentation
- SQL persistence via SQLx with parameterized queries
A complete ticketing system can be found at cinderblock-ticketing
Actions are not generic CRUD verbs -- they are domain-specific operations with their own types and input validation:
cinderblock_core::create::<Ticket, Open>(open_input, &ctx).await?;
cinderblock_core::update::<Ticket, Close>(&ticket_id, close_input, &ctx).await?;
cinderblock_core::destroy::<Ticket, Remove>(&ticket_id, &ctx).await?;Actions can restrict which fields they accept (accept [field1, field2]) and apply programmatic mutations via change_ref closures.
- InMemoryDataLayer (default) -- global
RwLock<HashMap>for prototyping - SqliteDataLayer (via
cinderblock-sqlx) -- full SQLite persistence using SQLx
Extensions hook into the resource! macro to generate additional code:
extensions {
cinderblock_json_api {}; // REST API with OpenAPI
cinderblock_sqlx { table = "my_table"; }; // SQL persistence
}| Crate | Description |
|---|---|
cinderblock-core |
Resource trait, CRUD functions, Context, in-memory data layer |
cinderblock-core-macros |
The resource! proc macro |
cinderblock-extension-api |
Shared DSL parser types for extension authors |
cinderblock-json-api |
JSON REST API extension (Axum router, OpenAPI, Swagger UI) |
cinderblock-json-api-macros |
JSON API extension proc macro |
cinderblock-sqlx |
SQLx data layer extension (SQLite) |
cinderblock-sqlx-macros |
SQLx extension proc macro |
# Core CRUD with in-memory storage
cargo run --example helpdesk -p cinderblock-core
# JSON API server with Swagger UI
cargo run --example helpdesk_api -p cinderblock-json-api --features swagger-uiThe API example starts a server on http://localhost:3000 with endpoints like:
GET /helpdesk/support/ticket
POST /helpdesk/support/ticket/open
PATCH /helpdesk/support/ticket/{id}/close
DELETE /helpdesk/support/ticket/{id}/remove
GET /openapi.json
Licensed under Apache-2.0.