在 API 资源中实现 webhook 订阅

Posted

技术标签:

【中文标题】在 API 资源中实现 webhook 订阅【英文标题】:implementing webhook subscription into an API resource 【发布时间】:2019-05-16 02:34:39 【问题描述】:

考虑以下带有以下路由的 vanilla api 资源:

`POST` `baseurl/api/v1/users`    
//with request body of 

    "username":"adam12",
    "password":"abc123"


`GET` `baseurl/api/v1/users`   
`GET` `baseurl/api/v1/users/:id`   
`PUT` `baseurl/api/v1/users/:id`   
`DELETE` `baseurl/api/v1/users/:id`

其中baseurllocalhost:3000

我在这里有一个工作实现的代码:https://github.com/mmcguff/webhookLearning

此时,与此 users 资源交互的客户端必须发送 GET 请求才能了解此资源的更改。如果您需要来自该资源的实时数据,则必须创建一个轮询循环,该循环消耗服务器端响应这些请求的两个客户端上的资源。

我知道这个问题的正确解决方案是为此资源实现 webhook 订阅,但我没有找到关于如何在 node.js 中执行此操作的明确最佳实践类型信息。我在 npm 中找到的包目前下载量很少,这让我相信肯定有其他人正在使用的更好的方法。

任何关于从 vanilla API 迁移到 webhook API 的帮助对我和社区中的每个人都非常有用。

【问题讨论】:

另一位开发人员建议也许我可以使用 socket.io 来帮助解决这个问题,但我不太确定。其他人知道这是否可以提供帮助以及如何使用它来创建一种对事件的订阅? 【参考方案1】:

这种类型的事情通常使用队列。例如,GitHub 很久以前就为 Ruby 开源了一个名为 resque 的软件。具体在 Node 中,您可以查看 bull。 Bull 使用 Redis 来存储类似于 resque 的排队事件。 Worker 订阅他们关心的事件并相应地处理它们。

现在为您的用例提供一个实用但有限的示例:

const Queue = require('bull');
const rp = require('request-promise');

const userQueue = new Queue('user');

app.post(`/v1/users`, (req, res) => 
  userQueue.add(username: req.body.username, email: req.body.email);
  return res.send(`OK`);
);

const userSubscribers = [
  
    hookUrl: `http://example.com/user-hook`
  
];

userQueue.process(job => 
  return Promise.all(userSubscribers.map(subscriber => 
    const options = 
      method: `POST`,
      uri: subscriber.hookUrl,
      body: job.data,
      json: true
    ;
    return rp(options);
  );
);

对于不同的权衡,您可以使用 Kafka 而不是 webhook。

【讨论】:

感谢约翰的回答。这与我最终为此创建的非常接近。现在我正在研究如何订阅特定事件。如果您对此有任何想法,请告诉我。

以上是关于在 API 资源中实现 webhook 订阅的主要内容,如果未能解决你的问题,请参考以下文章

在客户端 JavaScript 中实现 Webhook?

如何通过 webhook 在 PayPal API 中确认每月订阅的计费?

如何从Calendly获得现有的webhook(来自json的解析)?

通过 Rest Api 订阅 Microsoft Graph Api Webhook 不再有效

Facebook:用于订阅用户到 Facebook(webhook)以进行实时更改的图形 api 是啥

使用 Google Apps 脚本创建 Strava Webhook 订阅时出现问题