web-dev-qa-db-fra.com

Node et Express: comment implémenter un serveur de webhook de base

J'ai du mal à trouver des tutoriels. Je suis nouveau sur les webhooks et je ne les ai pas utilisés ou vus, au-delà de quelques descriptions de base sur la façon dont ils sont censés fonctionner.

Notre cas d'utilisation consiste à mettre à jour les utilisateurs de nos API lorsqu'il y a de nouveaux enregistrements. Puisque nous utilisons Kafka et que nous avons opté pour une "cohérence éventuelle", une autre utilisation pourrait consister à leur signaler des erreurs lorsque les enregistrements n'ont pas pu être lus/écrits correctement à partir de Kafka stream.

Donc, le concept de base pour autant que je puisse voir:

const express = require("express");
const router = express.Router();

const processSomething = callback => {
    setTimeout(callback, 20000);
}

router.post("/hook", (req, res, next) => {
    processSomething(() => {
        res.status(200).send({
            id: "ABC123",
            message: "New record added!"
        });
    });
});

module.exports = router;

Est-ce essentiellement ce pour quoi je vis? Les utilisateurs publieraient-ils sur ce point de terminaison, attendraient-ils une réponse, puis publieraient-ils à nouveau une fois la réponse reçue afin de se réinscrire? Y a-t-il un problème avec ce fonctionnement pendant une longue période ou même indéfiniment?

Je pourrais vraiment utiliser des exemples plus sophistiqués mais je ne les trouve tout simplement pas. La plupart de ce que vous trouvez lors de la recherche sur Google implique l'intégration de webhooks tiers, tels que Github, Slack, etc., pas personnalisé, ce que j'ai besoin de construire.

Je ne m'oppose pas non plus à une autre approche. Il suffit de rechercher le meilleur moyen d'aviser les utilisateurs de l'API des mises à jour et autres informations importantes.

7
Tsar Bomba

Les webhooks essaient d'avertir les utilisateurs des événements retardés mais ils le font de manière asynchrone. Votre code est synchrone, ce qui signifie que les utilisateurs doivent attendre la réponse. Je pense que ça devrait ressembler plus à ça

const express = require("express");
const router = express.Router();

const processSomething = callback => {
  setTimeout(callback, 20000);
}

router.post("/hook", (req, res, next) => {
  processSomething(() => {
    const webhookUrl = req.params.url;

    /**
     * Your Kafka action or something else. There
     * you should collect info about success or
     * fail of client's action.
     */

    /** 
     * Your API call to webhookUrl with 
     * your defined body about status of event
     */
  });

  res.status(200).send('OK')
});

module.exports = router;

où la fonction processSomething fait votre action de manière asynchrone et appelle l'API du client avec réponse mais votre route répond toujours avec réponse - 200 OK signifie que vous avez reçu le message du client.

Vous pouvez également déléguer le client notyfing sur le message de réussite/échec à un autre endroit de votre code, mais vous devez enregistrer webhookUrl pour cela. Dans le système d'événements, vous pouvez créer un événement (ou un simple message) où l'un des attributs est l'URL du client.

3
Grzegorz Gajda

Vous vous dirigez dans la bonne direction, mais je pense que vous cherchez simplement à créer une API RESTful. Voici un bon article de Scotch.io qui parle de la mise en place d'une API express simple. C'est un bon exemple car ils parlent de routage, de middleware et vous donnent même un exemple de travail avec une base de données. Ils utilisent également PostMan, qui est un outil de test d'API pratique.

EDIT: Op a indiqué qu'il cherchait en effet des documents sur des crochets Web et pas seulement une API RESTful ...

Dans ce cas, je recommanderais un modèle de sous-pub. J'utilise ce modèle parce que les hooks web comme l'API web hook de Github ou l'API cron job de GCP ne sont pas vraiment concernés par la réponse de votre API. Par conséquent, ce que je fais généralement, c'est que mes itinéraires de hook Web dans mon application émettent simplement un événement, puis résolvent la demande d'API envoyée à partir du hook Web. Ensuite, l'émetteur d'événement déclenchera un écouteur et le processus souhaité démarrera. Quelque chose comme ça...

const Router = require('express').Router();
const eventEmitter = require('./eventEmitter');
// sets event listener
const listener = require('./eventListener');

Router.post('/webhook', (req, res) => {
    eventEmitter.emit('pubsub', req.body);
    res.status(200).send('success');
});

module.exports = Router;

Et puis dans eventListener.js...

const emitter = require('./eventEmitter');

emitter.on('pubsub', function(requestBody) {
  // Do what you want
});

Une dernière chose, c'est un super pub nub que j'utilise sur d'autres projets. Ce qui est génial, c'est que vous pouvez créer des abonnements en utilisant la notation par points .

1
Max Baldwin

Pour autant que je comprends, un hookback est juste un point de terminaison qu'un service automatisé POST de manière automatisée, vous gérez les données puis envoyez une réponse, je ne pense pas que ce soit différent d'un REST api, a juste un nom funky.

Source: Je suis presque sûr d'avoir construit une API de webhook il y a quelques années et c'est ce que j'ai découvert

0
Anthony