Skip to main content

BackboneCrudHandler

Struct BackboneCrudHandler 

Source
pub struct BackboneCrudHandler<S, E, C, U, R>
where S: CrudService<E, C, U> + 'static, E: Serialize + Send + Sync + 'static, C: DeserializeOwned + Send + Sync + 'static, U: DeserializeOwned + Send + Sync + 'static, R: From<E> + Serialize + Send + Sync + 'static,
{ /* private fields */ }
Expand description

Generic Backbone CRUD handler that provides all 11 endpoints as an Axum router.

This handler wraps a CrudService implementation and generates all standard Backbone endpoints automatically.

§Type Parameters

  • S: Service implementing CrudService
  • E: Entity type
  • C: Create DTO type
  • U: Update DTO type
  • R: Response DTO type (must implement From<E>)

§Example

ⓘ
let user_crud = UserCrudService::new(user_service);
let routes = BackboneCrudHandler::<UserCrudService, UserAggregate, CreateUserDto, UpdateUserDto, UserResponseDto>
    ::routes(Arc::new(user_crud), "/api/v1/users");

Implementations§

Source§

impl<S, E, C, U, R> BackboneCrudHandler<S, E, C, U, R>
where S: CrudService<E, C, U> + 'static, E: Serialize + Send + Sync + Clone + EntityRepoMeta + 'static, C: DeserializeOwned + Send + Sync + 'static, U: DeserializeOwned + Send + Sync + 'static, R: From<E> + Serialize + Send + Sync + 'static,

Source

pub fn new(service: Arc<S>) -> Self

Source

pub fn routes(service: Arc<S>, base_path: &str) -> Router<()>
where S: Clone,

Create Axum router with all 16 Backbone endpoints (reads + writes).

Equivalent to read_routes(...).merge(write_routes(...)). Use the split variants when reads and writes need different middleware (e.g., public reads + authenticated writes).

§Routes Created
  1. GET {base_path} - List with pagination
  2. POST {base_path} - Create
  3. GET {base_path}/:id - Get by ID
  4. PUT {base_path}/:id - Full update
  5. PATCH {base_path}/:id - Partial update
  6. DELETE {base_path}/:id - Soft delete
  7. POST {base_path}/bulk - Bulk create
  8. POST {base_path}/upsert - Upsert
  9. GET {base_path}/trash - List deleted (with filters)
  10. POST {base_path}/:id/restore - Restore
  11. DELETE {base_path}/empty - Empty trash
  12. GET {base_path}/:id/deleted - Get deleted by ID
  13. DELETE {base_path}/trash/:id - Permanent delete from trash
  14. (Uses route 9 with filters)
  15. GET {base_path}/count - Count active entities
  16. GET {base_path}/trash/count - Count deleted entities
Source

pub fn read_routes(service: Arc<S>, base_path: &str) -> Router<()>
where S: Clone,

Create Axum router with only the read (GET) endpoints.

Safe to expose publicly (e.g., for reference data like countries or categories) without auth middleware. Pair with write_routes under an auth layer when mutations must be restricted.

§Routes Created
  • GET {base_path} - List with pagination
  • GET {base_path}/:id - Get by ID
  • GET {base_path}/trash - List deleted (with filters)
  • GET {base_path}/:id/deleted - Get deleted by ID
  • GET {base_path}/count - Count active entities
  • GET {base_path}/trash/count - Count deleted entities
Source

pub fn write_routes(service: Arc<S>, base_path: &str) -> Router<()>
where S: Clone,

Create Axum router with only the write (mutation) endpoints.

These routes should not be publicly exposed. Wrap them with an auth middleware (see BackboneCrudHandler module docs) before nesting into the application router.

§Routes Created
  • POST {base_path} - Create
  • POST {base_path}/bulk - Bulk create
  • POST {base_path}/upsert - Upsert
  • DELETE {base_path}/empty - Empty trash
  • DELETE {base_path}/trash/:id - Permanent delete from trash
  • PUT {base_path}/:id - Full update
  • PATCH {base_path}/:id - Partial update
  • DELETE {base_path}/:id - Soft delete
  • POST {base_path}/:id/restore - Restore

Auto Trait Implementations§

§

impl<S, E, C, U, R> Freeze for BackboneCrudHandler<S, E, C, U, R>

§

impl<S, E, C, U, R> RefUnwindSafe for BackboneCrudHandler<S, E, C, U, R>

§

impl<S, E, C, U, R> Send for BackboneCrudHandler<S, E, C, U, R>

§

impl<S, E, C, U, R> Sync for BackboneCrudHandler<S, E, C, U, R>

§

impl<S, E, C, U, R> Unpin for BackboneCrudHandler<S, E, C, U, R>

§

impl<S, E, C, U, R> UnsafeUnpin for BackboneCrudHandler<S, E, C, U, R>

§

impl<S, E, C, U, R> UnwindSafe for BackboneCrudHandler<S, E, C, U, R>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more