-
Notifications
You must be signed in to change notification settings - Fork 7
Home
In general, Webhooks are a common asynchronous means today for listening to key 'events' raised by online systems, typically over HTTPS.
The idea is straightforward:
- Register a callback URL to be called when an "event" of a certain type is going to be raised, and the system will POST you notification of that event (along with any data describing that event) to that callback URL when the event is raised.
- You first need to register the callback URL with the system for a specific event (which implies a specific DTO of the event data).
- Sit back and wait to be called at your callback URL.
Under the covers, Webhooks are a good example of pub/sub architectures, where the consumers of the events are (typically) decoupled from the producer of the events. It is generally an asynchronous eventing system for the web.
In this project, we are basing the subscription model of webhooks on that defined by GitHub Webhooks.
Which, defines the subscription service interface, and the wire representations of published events.
- Subscription Service Definition (except ping)
- Event Payloads
The WebhookFeature
will be a ServiceStack Plugin that installs the following:
- A fully implemented and secured
SubscriptionService
, that allows any subscriber to register a webhook to any event raised by any service (in the same AppHost). - A singleton service
IWebhooks
that will be used to raise any event from anywhere in any service in the AppHost. - An extensible framework where the developer can plugin selected technologies that fit their service architecture and runtime environment.
When you register the WebhookFeature
in your AppHost, it installs the subscriptions API, and the basic components to support raising events.
By default, the AppHostWebhookEventSink
is used as the event sink.
When events are raised to it, the sink queries the ISubscriptionsService.Search(eventName)
(in-proc) to fetch all the subscriptions to POST events to. It caches those subscriptions for a TTL (say 60s), to reduce the number of times the query for the same event is made (to avoid chatter as events are raised in your services). Then is dispatches the notification of that event to all registered subscribers (over HTTP). It will retry 3 times before giving up (EventServiceClient.Post
).
WARNING: The AppHostWebhookEventSink
can work well in testing, but it is going to slow down your service request times, as it has to notify each of the subscribers, and that network latency is added to the call time of your API (since it is done in-proc and on the same thread as that of the web request that raised the event).
- We recommend only using the
AppHostWebhookEventSink
in testing and non-production systems. - We recommend, configuring a
IWebhookEventSink
that scales better with your architecture, and decouples the raising of events from the notifying of subscribers.
You add webhooks to your ServiceStack project by simply registering (and customizing) the WebhookFeature
in your AppHost.cs.
public override void Configure(Container container)
{
// Register the ValidationFeature and AuthFeature first
Plugins.Add(new ValidationFeature());
Plugins.Add(new AuthFeature(...));
// Register your own IWebhookSubscriptionStore and IWebhookEventSink
container.Register<IWebhookSubscriptionStore>(new MyDbSubscriptionStore());
container.Register<IWebhookEventSink>(new MyAsyncEventSink());
Plugins.Add(new WebhookFeature
{
.. any customization for your environment
});
}
WARNING: In any production system you are going to need to register a IWebhookSubscriptionStore
and IWebhookEventSink
, since the built-in ones are really only designed for getting up and running quickly, and for testing.
See Getting Started for more details
There are several points of extensibility in the WebhookFeature
, and each may support their own customization:
By default the WebHookFeature
registers and configures the SubscriptionService
to provide an API for subscribers to manage their webhooks.
You can choose to turn this service off, and ship your own, and you can also configure the authorization roles that secure it.
See Subscription Service for more details on how to customize it
By default, the built-in MemoryWebhookSubscriptionStore
uses an MemoryCacheClient
store for storing subscriptions.
You should register a different IWebhookSubscriptionStore
that will persist subscriptions to some permanent (and perhaps distributed) store in your architecture.
These stores are typically provided by extensions to the ServiceStack.Webhooks
framework such as those listed in: Plugins
WARNING: The MemoryWebhookSubscriptionStore
is not designed for use in production systems. If you do NOT register your own IWebhookSubscriptionStore
your subscriptions will be lost when your AppHost restarts!
By default, the built-in AppHostWebhookEventSink
will relay events to all subscribers in the same thread that called IWebhooks.Publish<TDto>()
.
You should register a different IWebhookEventSink
that will decouple the raising of events from the relays of events to subscribers, using appropriate components in your architecture. (i.e. muti-threading, queues, async hooks etc.)
These kinds of sinks are typically provided by extensions to the ServiceStack.Webhooks
framework such as those listed in: Plugins
WARNING: The AppHostWebhookEventSink
is not designed for use in production systems. If you do NOT register your own IWebhookEventSink
your services will suffer unacceptable performance penalties.