Add Webhooks to Your API the Right Way
Add Webhooks to Your API the Right Way

In the last 10 years, APIs have gone from nice-to-have to must-have, certainly for Software-as-a-Service (SaaS) applications. At the same time, users today are more impatient and expect more instant and interconnected apps. To answer user needs, developers are now adding webhooks to their APIs. Webhooks are the mechanism through which data from an API can be delivered proactively, without receiving a request for each response. We’ve found that given loose constraints, there are many ways developers might implement webhooks.
This post shares some high-level insights behind why you should include webhooks and how to add them to your API the right way.
Why you want to create webhooks
An event-driven approach ensures you can send the right notification to the right application at the time it occurs.
Webhooks are an architectural pattern that enable developers to receive updates to data as they happen rather than polling for the latest updates. The investment you put in up front building a webhook-enabled API can save your system resources and delight developers and end users alike.
A typical API lets developers read the latest data from your application. Perhaps they can query for specific data and may even be able to write new data if they have appropriate permissions. These sort of CRUD operations (Create, Read, Update, and Delete) provide the basic elements needed to emulate the functionality of your application.
However, your application exists within a network of other applications. Since changes to your user data affects many others, you need a robust model that takes this reality into account. An event-driven approach ensures you can send the right notification to the right application at the time it occurs.
Let’s say one feature of your application includes contacts, each of which has a name, email address, and phone number. The moment a new contact is added to your application, some other application may want to use that data to send a text message, look up their email address in another system, or backup the contact data. Without a way to alert other applications when a new contact is added, you force them to constantly poll for new data.
Polling is bad for everyone. It’s taxing to servers on both sides, which spend most of their time and resources with requesting responses that contain nothing new. When there is data, it’s only as new as the polling interval, which means it might not even satisfy a user’s thirst for instant data access. Other than webhooks, the only way to have up-to-the-second access to new data is to poll every second. While some developers may try that, it’s not likely to be sustainable.
Webhooks will make your end users happy, delight developers who use your API, and give your servers a break. So how do you get yourself some of this triple-win?
Create your subscription endpoint
Before sending notifications as webhooks, you need to know what to send notifications about. That’s where a subscription endpoint comes in handy. Developers will “subscribe” to certain actions and tell you where to send notifications.
Note: You may be familiar with adding a single webhook URL into an admin interface when working with other APIs. That is called a static webhook and is not recommended for robust subscription notifications. Static webhooks can only notify one URL and are limited to a single set of criteria. Plus, a user needs to manually add every notification they want. By comparison, subscription webhooks allow a single application to receive multiple types of notifications. Each can be added via API so a user is not required to interact with each subscription set up.
For most apps implementing webhooks, they already have an API. Even if you’re starting fresh, you’re likely planning out the endpoints for your API, which map to resources in your app. Sticking with the example in the previous section, your app might store contacts. For your API, the endpoint would be something like /contacts
. You’ll make another endpoint for webhooks, such as /webhook
, and treat it like any resource for your API.
action | description |
---|---|
GET /webhook | List existing webhooks |
POST /webhook | Subscribe to a new webhook with details sent in JSON body |
GET /webhook/{id} | Retrieve details of an existing webhook |
PUT /webhook/{id} | Update an existing webhook with details sent in JSON body |
DELETE /webhook/{id} | Unsubscribe from an existing webhook |
Your /webhook
endpoint would likely have the actions listed above, which would allow you to list, create, read, update, and delete webhooks.
Important: You would need to store and retrieve the data with the same security that you use to access the other resources in your application. That is, an external developer shouldn’t be able to work with a webhook {id} that is not registered to the account of the authenticated user.
When creating or updating a webhook, developers will need to pass details in the body of the request. At a minimum, you’ll need to accept a resource or events to watch for changes and a target URL (where to send the notifications). A common convention is to use noun.verb notation for describing webhooks, such as contact.create and contact.update. Whatever you choose, be consistent, and remember to send it along with each notification.
You’ll want to think about what criteria you need to determine what notifications to send. For example, you might have notifications for all new contacts or for updates to a specific contact id. Start with just the most common events. It’s easy to add more events later, but painful to remove them, especially once developers are depending on them.
Of course, with your webhook endpoint set up, all this does is track the webhooks. You’ll need another process to actually identify the times when we need to send notifications.
Implement your webhook queue
Now that you have a way for developers to subscribe to webhooks and update settings, you're ready to start sending notifications when the criteria matches. But when should you check the criteria and send the notifications? There are a few approaches you can take, each with its own advantages, complexity, and scalability.
- Do it inline: This is the simplest and most naive approach and should be reserved for prototypes or test environments. When an event occurs that might activate a webhook (such as a user adds a new contact), check whether a webhook fits the criteria. For all webhooks that do match, fire off a connection to the URL on file. The questionable part, for scaling, is making the request inline while the end user waits. A better solution is to create a queue so you can better deal with timeouts and retries.
- Create a DB queue: When you send webhooks inline, all your code is in one place. With this option, you’ll be creating a record in your existing database for each notification you need to send. Rather than initiating a connection immediately, you’ll need a separate process to frequently look for new notifications and send them. Since the end user isn’t waiting, timeouts are not as big of a concern. And if you need to retry a notification, just keep it marked active until it succeeds or is called the maximum number of times.
- Use a proper queue: If you know you’ll need to scale your solution, use a tool specifically designed for that. You can use open source scalable queueing solutions like RabbitMQ or a service like Amazon Simple Queuing Service. This way, your interaction is limited to adding and removing “messages,” which tell you what webhooks to call. Like the DB queue, you need a separate process to consume items from the queue and send notifications. In addition to using a tool designed for this purpose, a proper queue also saves database resources for what it does best–providing data to your primary application.
Tip: Whichever choice you use for queuing your webhook notifications, you’ll want to send them as quickly as you can. It may be tempting to run a cron job every minute, but a minute is a long time to wait for someone who wants to see if your webhooks work.
This post has covered a few of the high-level architectural decisions you’ll need to make as you implement webhooks. In the future, we’ll look at methods of retrying webhooks, authenticating payloads, and other factors of successful webhooks, some of which is covered in the RESTHooks documentation.
Keep reading: Learn how to use webhooks with Zapier.
Want to be first to know about new webhook, API, and other developer posts? Be sure to subscribe to the engineering blog.
原文地址:https://zapier.com/engineering/webhook-design/
Add Webhooks to Your API the Right Way的更多相关文章
- Professional C# 6 and .NET Core 1.0 - Chapter 42 ASP.NET Web API
本文内容为转载,重新排版以供学习研究.如有侵权,请联系作者删除. 转载请注明本文出处: -------------------------------------------------------- ...
- 在Web Api中集成protobuf
安装WebApiContrib.Formatting.ProtoBuf Install-Package WebApiContrib.Formatting.ProtoBuf 注册ProtoBufForm ...
- ASP.NET Web API 异常日志记录
如果在 ASP.NET MVC 应用程序中记录异常信息,我们只需要在 Global.asax 的 Application_Error 中添加代码就可以了,比如: public class MvcApp ...
- [转载] FFmpeg API 变更记录
最近一两年内FFmpeg项目发展的速度很快,本来是一件好事.但是随之而来的问题就是其API(接口函数)一直在发生变动.这么一来基于旧一点版本的FFmpeg的程序的代码在最新的类库上可能就跑不通了. 例 ...
- [转]HTML5 classList API
Having thrust myself into the world of JavaScript and JavaScript Libraries, I've often wondered: Whe ...
- FFmpeg API 变更记录
最近一两年内FFmpeg项目发展的速度很快,本来是一件好事.但是随之而来的问题就是其API(接口函数)一直在发生变动.这么一来基于旧一点版本的FFmpeg的程序的代码在最新的类库上可能就跑不通了. 例 ...
- ASP.NET MVC和Web API中的Angular2 - 第1部分
下载源码 - 903.5 KB 内容 第1部分:Visual Studio 2017中的Angular2设置,基本CRUD应用程序,第三方模态弹出控件 第2部分:使用Angular2管道进行过滤/搜索 ...
- Using MongoDB with Web API and ASP.NET Core
MongoDB is a NoSQL document-oriented database that allows you to define JSON based documents which a ...
- twitter api
1,twurl安装 1.1,安装软件管理包工具,在管理员身份打开的cmd中执行: @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powersh ...
随机推荐
- vim 插件之solarized
solarized 其实算不上严格的插件,它只是一个主题,这个主题看起来还是很不错的.有一点,因为vim的最终效果还跟ubuntu终端配色有关,所以我们还需要进行其他的设置.具体过程如下 1.更改终端 ...
- Android子线程创建Handler方法
如果我们想在子线程上创建Handler,通过直接new的出来是会报异常的比如: new Thread(new Runnable() { public void run() { Handler hand ...
- Kafka框架基础
* Kafka框架基础 官网:kafka.apache.org 框架简介 Apache Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.Kaf ...
- 服务器TCP连接中 TIME_WAIT 状态过多
今天查看服务器的TCP连接数,发现其中 TIME_WAIT 状态的太多了: # netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a ...
- C#中Dictionary排序方式
转载自:https://www.cnblogs.com/5696-an/p/5625142.html 自定义类: https://files.cnblogs.com/files/xunhanliu/d ...
- 推荐《R数据可视化手册》高清英文版PDF+中文版PDF+源代码
绝大多数的绘图案例都是以强大.灵活制图而著称的R包ggplot2实现的,充分展现了ggplot2生动.翔实的一面.从如何画点图.线图.柱状图,到如何添加注解.修改坐标轴和图例,再到分面的使用和颜色的选 ...
- 最长回文字串 (The longest palindrome substring)
这两天去学了一下,觉得下面那篇文章写的很好,有例子,比较容易懂,所以转一下. 以下内容来自:hihoCoder: 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互 ...
- Unity 编辑器学习(三)之 Light & Baked
上一篇博客已经详细的介绍GI了,接下来我们讲点实际的,怎么烘焙场景及注意事项. 一.Light Property: Function: Type 当前灯光的类型.有四种类型:Directional, ...
- 实现一个函数clone,可以对JS中的5种数据类型(Number、String、Object、Array、Boolean)进行值复制
实现一个函数clone,可以对JS中的5种数据类型(Number.String.Object.Array.Boolean)进行值复制
- Java基础学习总结(21)——数组
一.数组的基本概念 数组可以看成是多个相同类型数据组合,对这些数据的统一管理. 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量. 数组的元素可以是任何数据类型,包括基 ...