In order to establish a solid communication through webhooks, both the publishers and the consumers have to respect their responsibilities. This blog post touches upon the responsibilities of the webhook consumer.
As a webhook consumer, one of the most important requirements is the fact that you must be high available. If there’s no guarantee on an acceptable SLA of the consumer, then webhooks are probably not the best design choice. In that case, it’s better to consider API polling or asynchronous communication through intermediate queues.
The webhook consumer does not control the pace at which the events arrive, this is dictated by the publisher. Therefore, the consumer must have sufficient scalability characteristics to be able to cope with fluctuating load. Next to that, the consumer often needs to implement some throttling mechanism in order to perform load levelling towards the event destination.
The order in which you process incoming webhooks is extremely important. When receiving a webhook request, the security validation must first kick-off. Once this has passed successfully, the event should be persisted and then acknowledged. Returning an HTTP 200/202 means you take ownership of the event. Once the message is acknowledged, you can start processing it towards the backend system, in an asynchronous way. Again, automated retry policies and means for human intervention are highly recommended.
As a webhook consumer, you mostly need to make a public HTTP endpoint available. Make sure you have the required infrastructure in place to handle DDoS attacks or use a cloud platform that takes care of that. Also think about rate limiting and IP whitelisting. Next to that, validate API keys or hash-based message authentication codes of the incoming requests, depending on the options the publisher provides.
Due to their asynchronous nature, ordering between events is not guaranteed. The webhook consumer needs to take this into account. Processing events in sequence is mostly not feasible or advised. It’s important to have a way to avoid that old events are overriding new events, in case you leverage webhooks for data synchronisation. This requires a little bit of state. Because of the retries, on both publisher and consumer side, the processing towards the event destination must be idempotent.
I hope this advice helps you to react in a stable way to webhooks.