pub struct WebhookRegistry { /* private fields */ }Expand description
Registry for managing webhook subscriptions.
WebhookRegistry stores webhook registrations in memory and provides
methods to sync them with Shopify via the GraphQL Admin API.
§Two-Phase Pattern
The registry follows a two-phase pattern:
- Add Registration (Local): Use
add_registrationto store webhook configuration in the in-memory registry - Register with Shopify (Remote): Use
registerorregister_allto sync registrations with Shopify
This pattern allows apps to configure webhooks at startup and register them later when a valid session is available.
§Thread Safety
WebhookRegistry is Send + Sync, making it safe to share across threads.
§Smart Registration
When registering webhooks, the registry performs “smart registration”:
- Queries existing subscriptions from Shopify
- Compares configuration to detect changes
- Only creates/updates when necessary
- Avoids unnecessary API calls
§Delivery Methods
The registry supports three delivery methods:
- HTTP: Webhooks delivered via HTTP POST to a callback URL
- EventBridge: Webhooks delivered to Amazon EventBridge
- Pub/Sub: Webhooks delivered to Google Cloud Pub/Sub
§Example
use shopify_sdk::webhooks::{WebhookRegistry, WebhookRegistrationBuilder, WebhookDeliveryMethod};
use shopify_sdk::rest::resources::v2025_10::common::WebhookTopic;
// Create a registry and add registrations
let mut registry = WebhookRegistry::new();
registry.add_registration(
WebhookRegistrationBuilder::new(
WebhookTopic::OrdersCreate,
WebhookDeliveryMethod::Http {
uri: "https://example.com/api/webhooks/orders".to_string(),
},
)
.build()
);
// Later, when you have a session:
// let results = registry.register_all(&session, &config).await?;Implementations§
Source§impl WebhookRegistry
impl WebhookRegistry
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new empty webhook registry.
§Example
use shopify_sdk::webhooks::WebhookRegistry;
let registry = WebhookRegistry::new();
assert!(registry.list_registrations().is_empty());Sourcepub fn add_registration(
&mut self,
registration: WebhookRegistration,
) -> &mut Self
pub fn add_registration( &mut self, registration: WebhookRegistration, ) -> &mut Self
Adds a webhook registration to the registry.
If a registration for the same topic already exists, it will be replaced.
If the registration contains a handler, the handler is extracted and stored
separately in the handlers map.
Returns &mut Self to allow method chaining.
§Arguments
registration- The webhook registration to add
§Example
use shopify_sdk::webhooks::{WebhookRegistry, WebhookRegistrationBuilder, WebhookDeliveryMethod};
use shopify_sdk::rest::resources::v2025_10::common::WebhookTopic;
let mut registry = WebhookRegistry::new();
// Method chaining with different delivery methods
registry
.add_registration(
WebhookRegistrationBuilder::new(
WebhookTopic::OrdersCreate,
WebhookDeliveryMethod::Http {
uri: "https://example.com/webhooks/orders/create".to_string(),
},
)
.build()
)
.add_registration(
WebhookRegistrationBuilder::new(
WebhookTopic::ProductsUpdate,
WebhookDeliveryMethod::EventBridge {
arn: "arn:aws:events:us-east-1::event-source/test".to_string(),
},
)
.build()
);
assert_eq!(registry.list_registrations().len(), 2);Sourcepub fn get_registration(
&self,
topic: &WebhookTopic,
) -> Option<&WebhookRegistration>
pub fn get_registration( &self, topic: &WebhookTopic, ) -> Option<&WebhookRegistration>
Gets a webhook registration by topic.
Returns None if no registration exists for the given topic.
§Arguments
topic- The webhook topic to look up
§Example
use shopify_sdk::webhooks::{WebhookRegistry, WebhookRegistrationBuilder, WebhookDeliveryMethod};
use shopify_sdk::rest::resources::v2025_10::common::WebhookTopic;
let mut registry = WebhookRegistry::new();
registry.add_registration(
WebhookRegistrationBuilder::new(
WebhookTopic::OrdersCreate,
WebhookDeliveryMethod::Http {
uri: "https://example.com/webhooks".to_string(),
},
)
.build()
);
// Found
assert!(registry.get_registration(&WebhookTopic::OrdersCreate).is_some());
// Not found
assert!(registry.get_registration(&WebhookTopic::ProductsCreate).is_none());Sourcepub fn list_registrations(&self) -> Vec<&WebhookRegistration>
pub fn list_registrations(&self) -> Vec<&WebhookRegistration>
Lists all webhook registrations in the registry.
Returns a vector of references to all registrations.
§Example
use shopify_sdk::webhooks::{WebhookRegistry, WebhookRegistrationBuilder, WebhookDeliveryMethod};
use shopify_sdk::rest::resources::v2025_10::common::WebhookTopic;
let mut registry = WebhookRegistry::new();
registry
.add_registration(
WebhookRegistrationBuilder::new(
WebhookTopic::OrdersCreate,
WebhookDeliveryMethod::Http {
uri: "https://example.com/webhooks/orders".to_string(),
},
)
.build()
)
.add_registration(
WebhookRegistrationBuilder::new(
WebhookTopic::ProductsCreate,
WebhookDeliveryMethod::PubSub {
project_id: "my-project".to_string(),
topic_id: "webhooks".to_string(),
},
)
.build()
);
let registrations = registry.list_registrations();
assert_eq!(registrations.len(), 2);Sourcepub async fn process(
&self,
config: &ShopifyConfig,
request: &WebhookRequest,
) -> Result<(), WebhookError>
pub async fn process( &self, config: &ShopifyConfig, request: &WebhookRequest, ) -> Result<(), WebhookError>
Processes an incoming webhook request.
This method verifies the webhook signature, looks up the appropriate handler, parses the payload, and invokes the handler.
§Flow
- Verify the webhook signature using
verify_webhook - Look up the handler by topic
- Parse the request body as JSON
- Invoke the handler with the context and payload
§Arguments
config- The Shopify configuration containing the API secret keyrequest- The incoming webhook request
§Errors
Returns WebhookError::InvalidHmac if signature verification fails.
Returns WebhookError::NoHandlerForTopic if no handler is registered for the topic.
Returns WebhookError::PayloadParseError if the body cannot be parsed as JSON.
Returns any error returned by the handler.
§Example
use shopify_sdk::webhooks::{WebhookRegistry, WebhookRequest};
let registry = WebhookRegistry::new();
// ... add registrations with handlers ...
// Process incoming webhook
registry.process(&config, &request).await?;Sourcepub async fn register(
&self,
session: &Session,
config: &ShopifyConfig,
topic: &WebhookTopic,
) -> Result<WebhookRegistrationResult, WebhookError>
pub async fn register( &self, session: &Session, config: &ShopifyConfig, topic: &WebhookTopic, ) -> Result<WebhookRegistrationResult, WebhookError>
Registers a single webhook with Shopify.
This method performs “smart registration”:
- Queries existing subscriptions from Shopify
- Compares configuration to detect changes
- Creates new subscription if none exists
- Updates existing subscription if configuration differs
- Returns
AlreadyRegisteredif configuration matches
§Arguments
session- The authenticated session for API callsconfig- The SDK configurationtopic- The webhook topic to register
§Errors
Returns WebhookError::RegistrationNotFound if the topic is not in the registry.
Returns WebhookError::GraphqlError for underlying API errors.
Returns WebhookError::ShopifyError for userErrors in the response.
§Example
use shopify_sdk::webhooks::{WebhookRegistry, WebhookRegistrationBuilder, WebhookDeliveryMethod};
use shopify_sdk::rest::resources::v2025_10::common::WebhookTopic;
let mut registry = WebhookRegistry::new();
registry.add_registration(
WebhookRegistrationBuilder::new(
WebhookTopic::OrdersCreate,
WebhookDeliveryMethod::Http {
uri: "https://example.com/webhooks/orders".to_string(),
},
)
.build()
);
let result = registry.register(&session, &config, &WebhookTopic::OrdersCreate).await?;Sourcepub async fn register_all(
&self,
session: &Session,
config: &ShopifyConfig,
) -> Vec<WebhookRegistrationResult>
pub async fn register_all( &self, session: &Session, config: &ShopifyConfig, ) -> Vec<WebhookRegistrationResult>
Registers all webhooks in the registry with Shopify.
Iterates through all registrations and calls register for each.
Continues processing even if individual registrations fail.
§Arguments
session- The authenticated session for API callsconfig- The SDK configuration
§Returns
A vector of results for each registration.
Individual registration failures are captured in WebhookRegistrationResult::Failed.
§Example
use shopify_sdk::webhooks::{WebhookRegistry, WebhookRegistrationBuilder, WebhookRegistrationResult, WebhookDeliveryMethod};
use shopify_sdk::rest::resources::v2025_10::common::WebhookTopic;
let mut registry = WebhookRegistry::new();
registry.add_registration(/* ... */);
let results = registry.register_all(&session, &config).await;
for result in results {
match result {
WebhookRegistrationResult::Created { id } => println!("Created: {}", id),
WebhookRegistrationResult::Failed(err) => println!("Failed: {}", err),
_ => {}
}
}Sourcepub async fn unregister(
&self,
session: &Session,
config: &ShopifyConfig,
topic: &WebhookTopic,
) -> Result<(), WebhookError>
pub async fn unregister( &self, session: &Session, config: &ShopifyConfig, topic: &WebhookTopic, ) -> Result<(), WebhookError>
Unregisters a webhook from Shopify.
Queries for the existing webhook subscription and deletes it.
§Arguments
session- The authenticated session for API callsconfig- The SDK configurationtopic- The webhook topic to unregister
§Errors
Returns WebhookError::SubscriptionNotFound if the webhook doesn’t exist in Shopify.
Returns WebhookError::GraphqlError for underlying API errors.
Returns WebhookError::ShopifyError for userErrors in the response.
§Example
use shopify_sdk::webhooks::WebhookRegistry;
use shopify_sdk::rest::resources::v2025_10::common::WebhookTopic;
let registry = WebhookRegistry::new();
registry.unregister(&session, &config, &WebhookTopic::OrdersCreate).await?;Sourcepub async fn unregister_all(
&self,
session: &Session,
config: &ShopifyConfig,
) -> Result<(), WebhookError>
pub async fn unregister_all( &self, session: &Session, config: &ShopifyConfig, ) -> Result<(), WebhookError>
Unregisters all webhooks in the registry from Shopify.
Iterates through all registrations and calls unregister for each.
Continues processing even if individual unregistrations fail.
§Arguments
session- The authenticated session for API callsconfig- The SDK configuration
§Errors
Returns the first error encountered, but continues processing all registrations.
§Example
use shopify_sdk::webhooks::WebhookRegistry;
let mut registry = WebhookRegistry::new();
// ... add registrations ...
registry.unregister_all(&session, &config).await?;