Backbone Core
Status: โ FULLY IMPLEMENTED Last Updated: 2026-06-06
๐ฆด Foundation for generic CRUD system with 11 standard endpoints
Backbone Core is a foundational library that provides generic CRUD (Create, Read, Update, Delete) operations for any entity in Backbone Framework. It implements 11 standard Backbone endpoints consistently across both HTTP REST and gRPC protocols.
๐ Table of Contents
๐ Documentation
In-depth guides live in docs/:
- architecture.md โ how the crate is structured
- usage.md โ wire up CRUD for your entity, with examples
- api-reference.md โ every endpoint, query param, and response shape
- configuration.md โ feature flags and runtime limits
- openapi.md โ generate & serve an OpenAPI/Swagger spec (feature
openapi)
๐ฏ Overview
Backbone Core is a protocol-agnostic, generic CRUD foundation that enables any service to automatically get:
- โ 11 Standard Backbone endpoints for every entity
- โ Both HTTP REST and gRPC protocol support
- โ Pagination, filtering, and sorting
- โ Bulk operations and soft delete
- โ Type-safe generic implementations
- โ
JSON or form-encoded request bodies (auto-detected by
Content-Type) - โ Production-ready error handling
- โ
Optional OpenAPI/Swagger schema generation (feature
openapi, default-off)
The 11 Backbone Endpoints
| # | HTTP Method | HTTP Endpoint | gRPC Method | Purpose |
|---|---|---|---|---|
| 1 | GET |
/api/v1/{collection} |
list() |
List with pagination, filtering, sorting |
| 2 | POST |
/api/v1/{collection} |
create() |
Create new entity |
| 3 | GET |
/api/v1/{collection}/:id |
get_by_id() |
Get entity by ID |
| 4 | PUT |
/api/v1/{collection}/:id |
update() |
Full entity update |
| 5 | PATCH |
/api/v1/{collection}/:id |
partial_update() |
Partial update (selected fields) |
| 6 | DELETE |
/api/v1/{collection}/:id |
soft_delete() |
Soft delete (mark as deleted) |
| 7 | POST |
/api/v1/{collection}/bulk |
bulk_create() |
Create multiple entities |
| 8 | POST |
/api/v1/{collection}/upsert |
upsert() |
Update or insert if not exists |
| 9 | GET |
/api/v1/{collection}/trash |
list_deleted() |
List deleted entities |
| 10 | POST |
/api/v1/{collection}/:id/restore |
restore() |
Restore soft-deleted entity |
| 11 | DELETE |
/api/v1/{collection}/empty |
empty_trash() |
Permanently delete all trash |
Atomic batch endpoints
All-or-nothing operations applied inside a single transaction: ids are validated
up-front, and if any id is missing (or already in the target state) the whole
batch is rolled back with 400 Bad Request โ no partial writes. Batches are
capped at MAX_BATCH_SIZE (1,000) items; larger payloads are rejected with
400. Lifecycle hooks and CRUD events fire per affected entity.
| HTTP Method | HTTP Endpoint | Service method | Purpose |
|---|---|---|---|
PUT |
/api/v1/{collection}/bulk |
bulk_update() |
Full-update many entities ([{ "id", ...fields }]) |
PATCH |
/api/v1/{collection}/bulk |
bulk_partial_update() |
Partial-update many โ shared { ids, patch } or per-id { items: [{ id, patch }] } |
POST |
/api/v1/{collection}/delete/bulk |
bulk_soft_delete() |
Soft-delete many by id ({ "ids": [...] }) |
POST |
/api/v1/{collection}/restore/bulk |
bulk_restore() |
Restore many soft-deleted by id |
POST |
/api/v1/{collection}/restore/all |
restore_all() |
Restore every soft-deleted entity |
DELETE |
/api/v1/{collection}/trash/bulk |
bulk_permanent_delete() |
Permanently delete many trashed by id |
๐ Features
๐ Protocol Agnostic
- HTTP REST: Standard REST endpoints with JSON responses
- gRPC: High-performance RPC with Protocol Buffers
- Same interface: Both protocols provide identical functionality
๐ Advanced CRUD Operations
- Pagination: Automatic pagination with metadata
- Depth-capped pagination: list/query endpoints return
400 Bad Requestonce a request would page beyondMAX_PAGINATION_OFFSET(10,000 rows โ ~100 pages at theMAX_PER_PAGEclamp of 100), avoiding expensive deepOFFSETscans and prompting clients to add filters instead. - Filtering: HashMap-based field filtering
- Sorting: Multi-field sorting with configurable order
- Sparse fieldsets: read endpoints (
list,get_by_id,list_deleted,get_deleted_by_id) accept?fields=a,b,cto trim each response object to the requested top-level keys plus the always-onid. Comma-separated, whitespace- trimmed; unknown keys are ignored and an empty/absent value returns every field.fields,include, andwithare reserved query keys โ stripped before filters reach the repository, so they never leak into theWHEREclause. - Relation expansion (
?include=):listandget_by_idaccept?include=<rel>(alias?with=) to hydrate declared to-one relations, injecting each related row as a sibling object keyed by the relation name. Comma-separated; only relations the entity declares are honored, unknown names are ignored. Batched โ oneWHERE id = ANY(...)per relation across the whole page (no N+1). Opt in per entity via theEntityRepoMeta::relations()hook (default none). Runs after field security and before sparse projection. v1 limitation: the expanded object is the raw related row (keys camelCased), not run through the target's response DTO or its@privatesecurity โ don't enable it for a target with private fields. See docs/api-reference.md. - Field-level security (
@private/@owner): read endpoints strip an entity's@privateresponse fields unless the caller may see them. An injectableAccessScope(Platform|Tenant(id), read from an axumExtensionset by your auth middleware) decides visibility:Platformsees all,Tenant(id)sees private fields only when the row's@ownerfield equalsid, and an absent scope fails closed. Opt in per entity via theEntityRepoMeta::private_fields()/owner_field()hooks (default no-op). Enforced before sparse projection, so it always beats a?fields=request. See docs/api-reference.md. - Client-error aware: list/query endpoints return
400 Bad Request(not500) when a bad filter or sort key produces a Postgrescolumn "..." does not exist(SQLSTATE 42703) orinvalid input syntaxerror โ e.g. a typo or a stray camelCase param likesortOrder. - Bulk Operations: Efficient bulk create and upsert
- Atomic batch operations: transactional, all-or-nothing bulk update / partial-update /
soft-delete / restore / permanent-delete โ a missing id rolls back the whole batch
(
400), and batches are capped atMAX_BATCH_SIZE(1,000) - Soft Delete: Trash management with restore functionality
๐จ Flexible Request Bodies
- JSON or form:
BackboneCrudHandlerdecodes create/update/upsert/bulk bodies via theJsonOrFormextractor, accepting bothapplication/jsonandapplication/x-www-form-urlencoded. - Lenient default: falls back to JSON when the
Content-Typeis missing or unrecognized. - Drop-in: use
JsonOrForm(x): JsonOrForm<T>anywhere you would writeJson(x): Json<T>in your own handlers.
๐ก๏ธ Type Safety
- Generic Types: Works with any entity implementing
Entitytrait - Compile-time Safety: Catch errors at compile time, not runtime
- Proper Error Handling: Comprehensive
anyhow::Errorsupport
๐ Usage
1. Add Dependency
[]
= "2.0.0"
2. Define Your Entity
use *;
use ;
use Uuid;
use ;
3. Implement HTTP Handler
use *;
use *;
;
4. Implement gRPC Service
use *;
;
๐ง Technical Details
Core Traits
Entity Trait
Repository Traits
- Repository - Basic CRUD operations
- SearchableRepository - Search and filtering
- SoftDeletableRepository - Soft delete operations
- PaginatedRepository - Pagination support
- BulkRepository - Bulk operations
๐ Examples
Pagination with Filtering
let list_request = ListRequest ;
๐งช Testing
Run Tests
# Run all tests
# Run integration tests (requires database)
๐ Dependencies
[]
= { = "1.0", = ["full"] }
= { = "1.0", = ["derive"] }
= "1.0"
= { = "1.0", = ["v4", "serde"] }
= { = "0.4", = ["serde"] }
= "1.0"
= "1.0"
# gRPC
= "0.12"
= "0.13"
# Web Framework
= "0.7"
= "0.4"
Feature flags
All optional capabilities are off by default (this crate is plumbing โ pull only what you need). See docs/configuration.md for the full matrix.
| Feature | Enables |
|---|---|
postgres / database |
sqlx-backed PostgresRepository |
prost |
Protobuf well-known types for gRPC |
openapi |
utoipa::ToSchema on the HTTP types + openapi::BackboneComponents |
full |
postgres + prost |
๐ค Contributing
- Follow existing code style
- Write tests for new features
- Update documentation
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ฆด Backbone Core - Foundation for generic CRUD operations