Consider the following vanilla api resource with the following routes:
`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`
where {{baseurl}}
is localhost:3000
.
I have the code for a working implementation of this here: https://github.com/mmcguff/webhookLearning
At this point clients interacting with this users
resource must send GET
requests in order to get made aware of changes to this resources. If you were needing real time data from this resource you would have to create a polling loop which consumes resources on both the client at the server answering these requests.
I know the right solution for this problem is to implement a webhook subscription for this resource but I have found no clear best practice type information on how to do this in node.js. The package I found in npm has very few downloads at the moment which leads me to believe there must be a better way that others are using.
Any help on what migration from a vanilla API to a webhook API would be great for me and everyone in the community.
It's common to use a queue for this type of thing. GitHub, for example, open sourced one for Ruby called resque a long while back. In Node specifically, you could look at bull. Bull uses Redis for storage of queued events similar to resque. Workers subscribe to events they care about and process them accordingly.
Now for a practical but limited example for your use case:
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);
});
});
For different tradeoffs, you could use Kafka instead of webhooks.