pub trait RestResource:
Serialize
+ DeserializeOwned
+ Clone
+ Send
+ Sync
+ Sized {
type Id: Display + Clone + Send + Sync;
type FindParams: Serialize + Default + Send + Sync;
type AllParams: Serialize + Default + Send + Sync;
type CountParams: Serialize + Default + Send + Sync;
const NAME: &'static str;
const PLURAL: &'static str;
const PATHS: &'static [ResourcePath];
const PREFIX: Option<&'static str> = None;
// Required method
fn get_id(&self) -> Option<Self::Id>;
// Provided methods
fn resource_key() -> String { ... }
async fn find(
client: &RestClient,
id: Self::Id,
params: Option<Self::FindParams>,
) -> Result<ResourceResponse<Self>, ResourceError> { ... }
async fn all(
client: &RestClient,
params: Option<Self::AllParams>,
) -> Result<ResourceResponse<Vec<Self>>, ResourceError> { ... }
async fn all_with_parent<ParentId: Display + Send>(
client: &RestClient,
parent_id_name: &str,
parent_id: ParentId,
params: Option<Self::AllParams>,
) -> Result<ResourceResponse<Vec<Self>>, ResourceError> { ... }
async fn save(&self, client: &RestClient) -> Result<Self, ResourceError> { ... }
async fn save_partial(
&self,
client: &RestClient,
changed_fields: Value,
) -> Result<Self, ResourceError> { ... }
async fn delete(&self, client: &RestClient) -> Result<(), ResourceError> { ... }
async fn count(
client: &RestClient,
params: Option<Self::CountParams>,
) -> Result<u64, ResourceError> { ... }
fn build_full_path(path: &str) -> String { ... }
}Expand description
A REST resource that can be fetched, created, updated, and deleted.
This trait provides a standardized interface for CRUD operations on Shopify REST API resources. Implementors define the resource’s paths, name, and parameter types, and get default implementations for all CRUD methods.
§Associated Types
Id: The type of the resource’s identifier (usuallyu64orString)FindParams: Parameters forfind()operations (use()if none)AllParams: Parameters forall()operations (pagination, filters, etc.)CountParams: Parameters forcount()operations
§Associated Constants
NAME: The singular resource name (e.g., “Product”)PLURAL: The plural form used in URLs (e.g., “products”)PATHS: Available paths for different operationsPREFIX: Optional path prefix for nested resources
§Required Bounds
Resources must be serializable, deserializable, cloneable, and thread-safe.
Required Associated Constants§
Sourceconst NAME: &'static str
const NAME: &'static str
The singular name of the resource (e.g., “Product”).
Used in error messages and as the response body key for single resources.
Sourceconst PLURAL: &'static str
const PLURAL: &'static str
The plural name used in URL paths (e.g., “products”).
Used as the response body key for collection operations.
Sourceconst PATHS: &'static [ResourcePath]
const PATHS: &'static [ResourcePath]
Available paths for this resource.
Define paths for each operation the resource supports. The path selection logic will choose the most specific path that matches the available IDs.
Provided Associated Constants§
Required Associated Types§
Sourcetype FindParams: Serialize + Default + Send + Sync
type FindParams: Serialize + Default + Send + Sync
Parameters for find() operations.
Use () if no parameters are needed.
Required Methods§
Provided Methods§
Sourcefn resource_key() -> String
fn resource_key() -> String
Returns the lowercase key used in JSON request/response bodies.
Sourceasync fn find(
client: &RestClient,
id: Self::Id,
params: Option<Self::FindParams>,
) -> Result<ResourceResponse<Self>, ResourceError>
async fn find( client: &RestClient, id: Self::Id, params: Option<Self::FindParams>, ) -> Result<ResourceResponse<Self>, ResourceError>
Finds a single resource by ID.
§Arguments
client- The REST client to use for the requestid- The resource ID to findparams- Optional parameters for the request
§Errors
Returns ResourceError::NotFound if the resource doesn’t exist.
Returns ResourceError::PathResolutionFailed if no valid path matches.
§Example
let product = Product::find(&client, 123, None).await?;
println!("Found: {}", product.title);Sourceasync fn all(
client: &RestClient,
params: Option<Self::AllParams>,
) -> Result<ResourceResponse<Vec<Self>>, ResourceError>
async fn all( client: &RestClient, params: Option<Self::AllParams>, ) -> Result<ResourceResponse<Vec<Self>>, ResourceError>
Lists all resources matching the given parameters.
Returns a paginated response. Use has_next_page() and next_page_info()
to navigate through pages.
§Arguments
client- The REST client to use for the requestparams- Optional parameters for filtering/pagination
§Errors
Returns ResourceError::PathResolutionFailed if no valid path matches.
§Example
let response = Product::all(&client, None).await?;
for product in response.iter() {
println!("Product: {}", product.title);
}
if response.has_next_page() {
// Fetch next page...
}Sourceasync fn all_with_parent<ParentId: Display + Send>(
client: &RestClient,
parent_id_name: &str,
parent_id: ParentId,
params: Option<Self::AllParams>,
) -> Result<ResourceResponse<Vec<Self>>, ResourceError>
async fn all_with_parent<ParentId: Display + Send>( client: &RestClient, parent_id_name: &str, parent_id: ParentId, params: Option<Self::AllParams>, ) -> Result<ResourceResponse<Vec<Self>>, ResourceError>
Lists resources with a specific parent resource ID.
For nested resources that require a parent ID (e.g., variants under products).
§Arguments
client- The REST client to useparent_id_name- The name of the parent ID parameter (e.g.,product_id)parent_id- The parent resource IDparams- Optional parameters for filtering/pagination
§Errors
Returns ResourceError::PathResolutionFailed if no valid path matches.
Sourceasync fn save(&self, client: &RestClient) -> Result<Self, ResourceError>
async fn save(&self, client: &RestClient) -> Result<Self, ResourceError>
Saves the resource (create or update).
For new resources (no ID), sends a POST request to create. For existing resources (has ID), sends a PUT request to update.
When updating, only changed fields are sent if dirty tracking is used.
§Arguments
client- The REST client to use
§Returns
The saved resource with any server-generated fields populated.
§Errors
Returns ResourceError::ValidationFailed if validation fails (422).
Returns ResourceError::NotFound if updating a non-existent resource.
§Example
// Create new
let mut product = Product { id: None, title: "New".to_string(), vendor: None };
let saved = product.save(&client).await?;
// Update existing
let mut product = Product::find(&client, 123, None).await?.into_inner();
product.title = "Updated".to_string();
let saved = product.save(&client).await?;Sourceasync fn save_partial(
&self,
client: &RestClient,
changed_fields: Value,
) -> Result<Self, ResourceError>
async fn save_partial( &self, client: &RestClient, changed_fields: Value, ) -> Result<Self, ResourceError>
Saves the resource with dirty tracking for partial updates.
For existing resources, only sends changed fields in the PUT request.
This is more efficient than save() for large resources.
§Arguments
client- The REST client to usechanged_fields- JSON value containing only the changed fields
§Returns
The saved resource with server-generated fields populated.
Sourceasync fn delete(&self, client: &RestClient) -> Result<(), ResourceError>
async fn delete(&self, client: &RestClient) -> Result<(), ResourceError>
Deletes the resource.
§Arguments
client- The REST client to use
§Errors
Returns ResourceError::NotFound if the resource doesn’t exist.
Returns ResourceError::PathResolutionFailed if no delete path exists.
§Example
let product = Product::find(&client, 123, None).await?;
product.delete(&client).await?;Sourceasync fn count(
client: &RestClient,
params: Option<Self::CountParams>,
) -> Result<u64, ResourceError>
async fn count( client: &RestClient, params: Option<Self::CountParams>, ) -> Result<u64, ResourceError>
Counts resources matching the given parameters.
§Arguments
client- The REST client to useparams- Optional parameters for filtering
§Returns
The count of matching resources as a u64.
§Errors
Returns ResourceError::PathResolutionFailed if no count path exists.
§Example
let count = Product::count(&client, None).await?;
println!("Total products: {}", count);Sourcefn build_full_path(path: &str) -> String
fn build_full_path(path: &str) -> String
Builds the full path including any prefix.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.