pub trait CrudService<Entity, CreateDto, UpdateDto>: Send + Syncwhere
Entity: Send + Sync + 'static,
CreateDto: Send + Sync + 'static,
UpdateDto: Send + Sync + 'static,{
type Error: Error + Send + Sync;
Show 28 methods
// Required methods
fn entity_name() -> &'static str;
fn list<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, u64), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn create<'life0, 'async_trait>(
&'life0 self,
dto: CreateDto,
) -> Pin<Box<dyn Future<Output = Result<Entity, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn get_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
dto: UpdateDto,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn partial_update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
fields: HashMap<String, Value>,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn soft_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn bulk_create<'life0, 'async_trait>(
&'life0 self,
items: Vec<CreateDto>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn upsert<'life0, 'async_trait>(
&'life0 self,
dto: CreateDto,
) -> Pin<Box<dyn Future<Output = Result<Entity, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn list_deleted<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, u64), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn restore<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn empty_trash<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn get_deleted_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn permanent_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn list_deleted_filtered<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, u64), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn count_active<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
fn aggregate<'life0, 'life1, 'async_trait>(
&'life0 self,
spec: &'life1 AggregateSpec,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<AggregateResult, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn count_deleted<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait;
// Provided methods
fn fetch_related_json<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_table: &'life1 str,
_ids: &'life2 [String],
) -> Pin<Box<dyn Future<Output = Vec<Value>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait { ... }
fn list_with_info<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, PaginationInfo), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn table_name(&self) -> Option<&str> { ... }
fn count_active_filtered<'life0, 'async_trait>(
&'life0 self,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn bulk_soft_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn bulk_restore<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn bulk_permanent_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn restore_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn bulk_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, UpdateDto)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
fn bulk_partial_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, HashMap<String, Value>)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait,
'life0: 'async_trait { ... }
}Expand description
Core trait that application services must implement for generic CRUD operations.
This trait provides the contract for all 11 standard Backbone endpoints. Module-specific services implement this trait with their entity types.
§Type Parameters
Entity: The domain entity typeCreateDto: DTO for create operationsUpdateDto: DTO for update operations
§Example
#[async_trait]
impl CrudService<User, CreateUserDto, UpdateUserDto> for UserCrudService {
type Error = ApplicationError;
fn entity_name() -> &'static str { "User" }
// ... implement all methods
}Required Associated Types§
Required Methods§
Sourcefn entity_name() -> &'static str
fn entity_name() -> &'static str
Entity name for error messages (e.g., “User”, “Role”)
Sourcefn list<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, u64), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, u64), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- List entities with pagination and filters
Sourcefn create<'life0, 'async_trait>(
&'life0 self,
dto: CreateDto,
) -> Pin<Box<dyn Future<Output = Result<Entity, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn create<'life0, 'async_trait>(
&'life0 self,
dto: CreateDto,
) -> Pin<Box<dyn Future<Output = Result<Entity, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Create a new entity
Sourcefn get_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
- Get entity by ID
Sourcefn update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
dto: UpdateDto,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
dto: UpdateDto,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
- Full update of entity
Sourcefn partial_update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
fields: HashMap<String, Value>,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn partial_update<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
fields: HashMap<String, Value>,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
- Partial update with specific fields
Sourcefn soft_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn soft_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
- Soft delete entity
Sourcefn bulk_create<'life0, 'async_trait>(
&'life0 self,
items: Vec<CreateDto>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_create<'life0, 'async_trait>(
&'life0 self,
items: Vec<CreateDto>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Bulk create multiple entities
Sourcefn upsert<'life0, 'async_trait>(
&'life0 self,
dto: CreateDto,
) -> Pin<Box<dyn Future<Output = Result<Entity, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn upsert<'life0, 'async_trait>(
&'life0 self,
dto: CreateDto,
) -> Pin<Box<dyn Future<Output = Result<Entity, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Upsert (create or update)
Sourcefn list_deleted<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, u64), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_deleted<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, u64), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- List deleted entities (trash)
Sourcefn restore<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn restore<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
- Restore soft-deleted entity
Sourcefn empty_trash<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn empty_trash<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Permanently delete all soft-deleted entities
Sourcefn get_deleted_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn get_deleted_by_id<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<Option<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
- Get deleted entity by ID (from trash)
Sourcefn permanent_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn permanent_delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 str,
) -> Pin<Box<dyn Future<Output = Result<bool, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
- Permanently delete a single soft-deleted entity by ID
Sourcefn list_deleted_filtered<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, u64), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_deleted_filtered<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, u64), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- List deleted entities with filters
Sourcefn count_active<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn count_active<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Count active (non-deleted) entities
Sourcefn aggregate<'life0, 'life1, 'async_trait>(
&'life0 self,
spec: &'life1 AggregateSpec,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<AggregateResult, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn aggregate<'life0, 'life1, 'async_trait>(
&'life0 self,
spec: &'life1 AggregateSpec,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<AggregateResult, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Group and reduce the rows list would return, under the same filters.
The default refuses rather than inventing an answer — see the repository trait for why a zero-filled default would be worse than an error.
Provided Methods§
Hydrate ?include= relations: fetch rows from table by id list, as JSON.
Default: no expansion. GenericCrudService delegates to its repository.
Sourcefn list_with_info<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, PaginationInfo), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn list_with_info<'life0, 'async_trait>(
&'life0 self,
page: u32,
limit: u32,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<(Vec<Entity>, PaginationInfo), Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
list, carrying the pagination info (cursor positions included) so
the HTTP layer can surface keyset paging. Default: the tuple form —
generated services override this with the repository’s cursors.
Sourcefn table_name(&self) -> Option<&str>
fn table_name(&self) -> Option<&str>
The schema-qualified table this service reads, when it has one.
Used to key a record’s history. Derived from the mount path instead, this would silently return an empty history whenever a route segment and a Postgres schema disagreed — so it is read from the repository, which is the same string the capture trigger writes.
Sourcefn count_active_filtered<'life0, 'async_trait>(
&'life0 self,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn count_active_filtered<'life0, 'async_trait>(
&'life0 self,
filters: HashMap<String, String>,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Count active entities MATCHING the caller’s filters.
The generated client has always sent filters to /count; the handler
never read them, so a filtered count silently answered with the whole
table. Nothing caught it because the wrong number is a plausible one.
The default delegates to list, whose total is already built from the
same where-clause as its data query — so the filtered count is correct
by construction rather than by a second implementation of the same
filter parsing, which is exactly how the two drifted apart. It asks for
a single row because the rows are discarded; an implementor that can
count without fetching may override.
Sourcefn bulk_soft_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_soft_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Soft-delete many entities by id. Returns the number affected.
Sourcefn bulk_restore<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_restore<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Restore many soft-deleted entities by id. Returns the restored rows.
Sourcefn bulk_permanent_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_permanent_delete<'life0, 'async_trait>(
&'life0 self,
ids: Vec<String>,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Permanently delete many soft-deleted entities by id.
Sourcefn restore_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn restore_all<'life0, 'async_trait>(
&'life0 self,
) -> Pin<Box<dyn Future<Output = Result<u64, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Restore every soft-deleted entity. Returns the number restored.
Default is a no-op (0) — only the GenericCrudService blanket impl can
perform this without an id list.
Sourcefn bulk_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, UpdateDto)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, UpdateDto)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Full-update many entities. Each item is
(id, UpdateDto).
Sourcefn bulk_partial_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, HashMap<String, Value>)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn bulk_partial_update<'life0, 'async_trait>(
&'life0 self,
items: Vec<(String, HashMap<String, Value>)>,
) -> Pin<Box<dyn Future<Output = Result<Vec<Entity>, Self::Error>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
- Partial-update many entities. Each item is
(id, field_map).
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementors§
Source§impl<E, C, U, R> CrudService<E, C, U> for GenericCrudService<E, C, U, R>where
E: PersistentEntity + Clone + Serialize + DeserializeOwned + FromCreateDto<C> + ApplyUpdateDto<U> + Send + Sync + 'static,
C: Send + Sync + 'static,
U: Send + Sync + 'static,
R: CrudRepository<E> + Send + Sync + 'static,
Blanket impl so that any GenericCrudService<E, C, U, R> automatically
satisfies CrudService<E, C, U> without generated adapter structs.
impl<E, C, U, R> CrudService<E, C, U> for GenericCrudService<E, C, U, R>where
E: PersistentEntity + Clone + Serialize + DeserializeOwned + FromCreateDto<C> + ApplyUpdateDto<U> + Send + Sync + 'static,
C: Send + Sync + 'static,
U: Send + Sync + 'static,
R: CrudRepository<E> + Send + Sync + 'static,
Blanket impl so that any GenericCrudService<E, C, U, R> automatically
satisfies CrudService<E, C, U> without generated adapter structs.
Generated code emits only a type alias:
pub type UserService = GenericCrudService<User, CreateUserDto, UpdateUserDto, UserRepository>;
That alias now directly implements CrudService and can be passed to
BackboneCrudHandler without any additional boilerplate.