Développer des plug-ins personnalisés

Vous consultez la documentation Apigee Edge.
Accéder à la documentation d'Apigee X
en savoir plus

Edge Microgateway version 3.3.x

Audience

Cette rubrique est destinée aux développeurs qui souhaitent étendre les fonctionnalités d'Edge Microgateway en écrivant des plug-ins personnalisés. Si vous souhaitez écrire un nouveau plug-in, une expérience de JavaScript et de Node.js est requise.

Qu'est-ce qu'un plug-in Edge Microgateway personnalisé ?

Un plug-in est un module Node.js qui ajoute des fonctionnalités à Edge Microgateway. Les modules de plug-ins suivent un modèle cohérent et sont stockés dans un emplacement connu d'Edge Microgateway, ce qui permet de les détecter et de les exécuter automatiquement. Plusieurs plug-ins prédéfinis sont fournis lors de l'installation d'Edge Microgateway. Ces outils incluent des plug-ins pour l'authentification, l'arrêt des pics, les quotas et l'analyse. Les plug-ins existants sont décrits dans la section Utiliser des plug-ins.

Vous pouvez ajouter de nouvelles fonctionnalités à la microgateway en écrivant des plug-ins personnalisés. Par défaut, Edge Microgateway est essentiellement un proxy pass-through sécurisé qui transmet les requêtes et les réponses inchangées depuis et vers les services cibles. Avec les plug-ins personnalisés, vous pouvez interagir de manière programmatique avec les requêtes et les réponses qui transitent par la micropasserelle.

Où placer le code du plug-in personnalisé ?

Un dossier de plug-ins personnalisés est inclus dans le cadre de l'installation d'Edge Microgateway ici:

[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins

[prefix] est le répertoire de préfixe npm, comme décrit dans la section "Où Edge Microgateway est-elle installée ?" de la section Installer Edge Microgateway.

Vous pouvez modifier ce répertoire de plug-in par défaut. Consultez la section Où trouver des plug-ins.

Examiner les plug-ins prédéfinis

Avant d'essayer de développer votre propre plug-in, il est recommandé de vérifier qu'aucun des plug-ins prédéfinis ne répond à vos exigences. Ces plug-ins se trouvent à l'emplacement suivant:

[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins

[prefix] est le répertoire de préfixe npm. Consultez également la section "Où Edge Microgateway est-elle installée ?" dans Installer Edge Microgateway.

Pour plus d'informations, consultez également la section Plug-ins prédéfinis fournis avec Edge Microgateway.

Écrire un plug-in simple

Dans cette section, nous allons passer en revue les étapes requises pour créer un plug-in simple. Ce plug-in remplace les données de réponse (quelles qu'elles soient) par la chaîne "Hello, World!" et les imprime sur le terminal.

  1. Si Edge Microgateway est en cours d'exécution, arrêtez-le maintenant:
    edgemicro stop
    
  2. cd dans le répertoire du plug-in personnalisé:

    cd [prefix]/lib/node_modules/edgemicro/plugins

    [prefix] est le répertoire de préfixe npm, comme décrit dans la section "Où Edge Microgateway est-elle installée ?" de la section Installer Edge Microgateway.

  3. Créez un projet de plug-in appelé response-override et ajoutez-y cd:
    mkdir response-override && cd response-override
    
  4. Créez un projet Node.js:
    npm init
    
    Appuyez plusieurs fois sur "Retour" pour accepter les valeurs par défaut.
  5. Utilisez un éditeur de texte pour créer un fichier appelé index.js.
  6. Copiez le code suivant dans index.js, puis enregistrez le fichier.
    'use strict';
    var debug = require('debug')
    
    module.exports.init = function(config, logger, stats) {
    
      return {
       
        ondata_response: function(req, res, data, next) {
          debug('***** plugin ondata_response');
          next(null, null);
        },
        
        onend_response: function(req, res, data, next) {
          debug('***** plugin onend_response');
          next(null, "Hello, World!\n\n");
        }
      };
    }
    
  7. Vous avez maintenant créé un plug-in et vous devez l'ajouter à la configuration Edge Microgateway. Ouvrez le fichier $HOME/.edgemicro/[org]-[env]-config.yaml, où org et env sont les noms de votre organisation Edge et de votre environnement.
  8. Ajoutez le plug-in response-override à l'élément plugins:sequence, comme indiqué ci-dessous.
          ...
          
          plugins:
            dir: ../plugins
            sequence:
              - oauth
              - response-override
              
          ...
    
  9. Redémarrez Edge Microgateway.
  10. appeler une API via Edge Microgateway ; (Pour cet appel d'API, nous partons du principe que vous avez défini la même configuration que celle du tutoriel concernant la sécurité des clés API, comme décrit dans Configurer Edge Microgateway:
    curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo
    Hello, World!
    

Anatomie d'un plug-in

L'exemple de plug-in Edge Microgateway suivant illustre le modèle à suivre pour développer vos propres plug-ins. Le code source de l'exemple de plug-in décrit dans cette section se trouve dans plugins/header-uppercase/index.js..

  • Les plug-ins sont des modules NPM standards dont le dossier racine contient package.json et index.js.
  • Un plug-in doit exporter une fonction init().
  • La fonction init() comporte trois arguments: config, logger et stats. Ces arguments sont décrits dans la section Arguments de la fonction init() du plug-in.
  • init() renvoie un objet avec des gestionnaires de fonctions nommés qui sont appelés lorsque certains événements se produisent au cours d'une requête.

Fonctions du gestionnaire d'événements

Un plug-in doit implémenter tout ou partie de ces fonctions de gestionnaire d'événements. La mise en œuvre de ces fonctions vous appartient. N'importe quelle fonction est facultative, et un plug-in classique met en œuvre au moins un sous-ensemble de ces fonctions.

Gestionnaires d'événements de flux de requêtes

Ces fonctions sont appelées lors d'événements de requête dans Edge Microgateway.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

Fonction onrequest

Appelée au début de la requête du client. Cette fonction se déclenche lorsque le premier octet de la requête est reçu par Edge Microgateway. Cette fonction vous donne accès aux en-têtes de requête, à l'URL, aux paramètres de requête et à la méthode HTTP. Si vous appelez "next" avec un premier argument vrai (comme une instance d'erreur), le traitement de la requête s'arrête et aucune requête cible n'est lancée.

Exemple :

onrequest: function(req, res, next) {
      debug('plugin onrequest');
      req.headers['x-foo-request-start'] = Date.now();
      next();
    }

Fonction ondata_request

Appelée lorsqu'un fragment de données est reçu du client. Transmet les données de requête au plug-in suivant dans la séquence de plug-ins. La valeur renvoyée par le dernier plug-in de la séquence est envoyée à la cible. Un cas d'utilisation typique, présenté ci-dessous, consiste à transformer les données de la requête avant de les envoyer à la cible.

Exemple :

ondata_request: function(req, res, data, next) {
      debug('plugin ondata_request ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    }

Fonction onend_request

Appelée lorsque toutes les données de la requête ont été reçues du client.

Exemple :

onend_request: function(req, res, data, next) {
      debug('plugin onend_request');
      next(null, data);
    }

Fonction onclose_request

Indique que la connexion client s'est fermée. Vous pouvez utiliser cette fonction lorsque la connexion client n'est pas fiable. Elle est appelée lorsque la connexion du socket au client est fermée.

Exemple :

onclose_request: function(req, res, next) {
      debug('plugin onclose_request');
      next();
    }

Fonction onerror_request

Appelée en cas d'erreur de réception de la requête du client.

Exemple :

onerror_request: function(req, res, err, next) {
      debug('plugin onerror_request ' + err);
      next();
    }

Gestionnaires d'événements de flux de réponse

Ces fonctions sont appelées sur des événements de réponse dans Edge Microgateway.

  • onresponse
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

Fonction onresponse

Appelée au début de la réponse cible. Cette fonction se déclenche lorsque le premier octet de la réponse est reçu par Edge Microgateway. Cette fonction vous donne accès aux en-têtes de réponse et au code d'état.

Exemple :

onresponse: function(req, res, next) {      
    debug('plugin onresponse');     
    res.setHeader('x-foo-response-time', Date.now() - req.headers['x-foo-request-start'])    
    next();    
}


Fonction ondata_response

Appelée lorsqu'un fragment de données est reçu de la cible.

Exemple :

ondata_response: function(req, res, data, next) {
      debug('plugin ondata_response ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    }


Fonction onend_response

Appelée lorsque toutes les données de réponse ont été reçues de la cible.

Exemple :

onend_response: function(req, res, data, next) {
      debug('plugin onend_response');
      next(null, data);
    }

Fonction onclose_response

Indique que la connexion cible est fermée. Vous pouvez utiliser cette fonction lorsque la connexion cible n'est pas fiable. Elle est appelée lorsque la connexion du socket à la cible est fermée.

Exemple :

onclose_response: function(req, res, next) {
      debug('plugin onclose_response');
      next();
    }


Fonction onerror_response

Appelée en cas d'erreur lors de la réception de la réponse cible.

Exemple :

onerror_response: function(req, res, err, next) {
      debug('plugin onerror_response ' + err);
      next();
    }

Ce que vous devez savoir sur les fonctions du gestionnaire d'événements de plug-in

Les fonctions du gestionnaire d'événements de plug-in sont appelées en réponse à des événements spécifiques qui se produisent pendant que Edge Microgateway traite une requête API donnée.

  • Chacun des gestionnaires de fonctions init() (ondata_request, ondata_response, etc.) doit appeler le rappel next() une fois le traitement terminé. Si vous n'appelez pas next(), le traitement s'interrompt et la requête se bloque.
  • Le premier argument de next() peut être une erreur qui entraîne l'arrêt du traitement de la requête.
  • Les gestionnaires ondata_ et onend_ doivent appeler next() avec un deuxième argument contenant les données à transmettre à la cible ou au client. Cet argument peut être nul si le plug-in effectue une mise en mémoire tampon et ne dispose pas de suffisamment de données pour effectuer la transformation pour le moment.
  • Notez qu'une seule instance du plug-in est utilisée pour traiter toutes les requêtes et les réponses. Si un plug-in souhaite conserver l'état par requête entre les appels, il peut l'enregistrer dans une propriété ajoutée à l'objet request fourni (req), dont la durée de vie correspond à celle de l'appel d'API.
  • Veillez à intercepter toutes les erreurs et à appeler next() avec l'erreur concernée. Si vous n'appelez pas next(), l'appel d'API est suspendu.
  • Veillez à ne pas introduire de fuites de mémoire, car elles pourraient affecter les performances globales d'Edge Microgateway et entraîner le plantage de l'instance en cas de manque de mémoire.
  • Veillez à suivre le modèle Node.js en n'effectuant pas de tâches gourmandes en ressources de calcul dans le thread principal, car cela peut affecter les performances d'Edge Microgateway.

À propos de la fonction init() du plug-in

Cette section décrit les arguments transmis à la fonction init() : config, logger et stats.

config

Les données de configuration obtenues en fusionnant le fichier de configuration Edge Microgateway avec les données téléchargées depuis Apigee Edge sont placées dans un objet nommé config.

Pour ajouter un paramètre de configuration appelé param avec la valeur foo à un plug-in appelé response-override, placez ceci dans le fichier default.yaml:

response-override:
    param: foo

Vous pouvez ensuite accéder au paramètre dans le code de votre plug-in, comme ceci:

// Called when response data is received
    ondata_response: function(req, res, data, next) {
      debug('***** plugin ondata_response');
      debug('***** plugin ondata_response: config.param: ' + config.param);
      next(null, data);
    },

Dans ce cas, "foo" s'affiche dans la sortie de débogage du plug-in:

Sun, 13 Dec 2015 21:25:08 GMT plugin:response-override ***** plugin ondata_response: config.param: foo

Vous pouvez accéder à la configuration de micro-passerelle fusionnée et aux données Apigee Edge téléchargées dans l'objet enfant config.emgConfigs. Par exemple, vous pouvez accéder à ces données de configuration dans la fonction init comme suit:

module.exports.init = function(config, logger, stats) {
   let emgconfigs = config.emgConfigs;

Vous trouverez ci-dessous un exemple de données que contient emgConfigs:

{
    edgemicro:
    {
        port: 8000,
        max_connections: 1000,
        config_change_poll_interval: 600,
        logging:
        {
            level: 'error',
            dir: '/var/tmp',
            stats_log_interval: 60,
            rotate_interval: 24,
            stack_trace: false
        },
        plugins: { sequence: [Array] },
        global: { org: 'Your Org', env: 'test' }
    },
    headers:
    {
        'x-forwarded-for': true,
        'x-forwarded-host': true,
        'x-request-id': true,
        'x-response-time': true,
        via: true
    },
    proxies:
    [    {
                max_connections: 1000,
                name: 'edgemicro_delayed',
                revision: '1',
                proxy_name: 'default',
                base_path: '/edgemicro_delayed',
                target_name: 'default',
                url: 'https://httpbin.org/delay/10',
                timeout: 0
            }
    ],
    product_to_proxy: { EdgeMicroTestProduct: [ 'edgemicro-auth','edgemicro_delayed',] },
    product_to_scopes: {prod4: [ 'Admin', 'Guest', 'Student' ] },
    product_to_api_resource: { EdgeMicroTestProduct: [ '/*' ] },
    _hash: 0,
    keys: { key: 'Your key', secret: 'Your key ' },
    uid: 'Internally generated uuid',
    targets: []
  }

logger

Enregistreur système L'enregistreur actuellement utilisé exporte ces fonctions, où l'objet peut être une chaîne, une requête HTTP, une réponse HTTP ou une instance d'erreur.

  • info(object, message)
  • warn(object, message)
  • error(object, message)
  • trace(object, message)
  • debug(object, message)

stats

Objet qui contient le nombre de requêtes, de réponses, d'erreurs et d'autres statistiques agrégées liées aux requêtes et aux réponses qui transitent par une instance de microgateway.

  • treqErrors : nombre de requêtes cibles comportant des erreurs.
  • treqErrors : nombre de réponses cibles comportant des erreurs.
  • statusCodes : un objet contenant le nombre de codes de réponse :
{
  1: number of target responses with 1xx response codes
  2: number of target responses with 2xx response codes
  3: number of target responses with 3xx response codes
  4: number of target responses with 4xx response codes
  5: number of target responses with 5xx response codes
  }
  
  • requests : nombre total de requêtes.
  • responses : le nombre total de réponses.
  • connections : nombre de connexions cibles actives.

À propos de la fonction next()

Toutes les méthodes de plug-in doivent appeler next() pour continuer le traitement de la méthode suivante de la série (sinon, le processus du plug-in se bloquera). Dans le cycle de vie de la requête, la première méthode appelée est onrequest(). La méthode suivante à appeler est la méthode ondata_request(). Cependant, ondata_request n'est appelée que si la requête inclut des données, comme dans le cas d'une requête POST. La prochaine méthode appelée sera onend_request(), qui est appelée une fois le traitement de la requête terminé. Les fonctions onerror_* ne sont appelées qu'en cas d'erreur et vous permettent de les gérer avec du code personnalisé si vous le souhaitez.

Supposons que des données soient envoyées dans la requête et que ondata_request() soit appelé. Notez que la fonction appelle next() avec deux paramètres:

next(null, data);

Par convention, le premier paramètre est utilisé pour transmettre des informations d'erreur, que vous pouvez ensuite gérer dans une fonction ultérieure de la chaîne. En le définissant sur null, un argument fausse, nous disons qu'il n'y a pas d'erreur et que le traitement des requêtes doit se dérouler normalement. Si cet argument est vrai (par exemple, un objet Error), le traitement de la requête s'arrête et celle-ci est envoyée à la cible.

Le deuxième paramètre transmet les données de la requête à la fonction suivante de la chaîne. Si vous n'effectuez aucun traitement supplémentaire, les données de la requête sont transmises telles quelles à la cible de l'API. Toutefois, vous pouvez modifier les données de la requête dans cette méthode et transmettre la requête modifiée à la cible. Par exemple, si les données de la requête sont au format XML et que la cible attend du format JSON, vous pouvez ajouter du code à la méthode ondata_request() qui (a) remplace le Content-Type de l'en-tête de requête par application/json et convertit les données de requête au format JSON selon le mode de votre choix (par exemple, vous pouvez utiliser un convertisseur Node.js xml2json obtenu à partir de NPM).

Voyons à quoi cela pourrait ressembler:

ondata_request: function(req, res, data, next) {
  debug('****** plugin ondata_request');
  var translated_data = parser.toJson(data);
  next(null, translated_data);
},

Dans ce cas, les données de la requête (qui sont censées être XML) sont converties au format JSON, et les données transformées sont transmises via next() à la fonction suivante de la chaîne de requête, avant d'être transmises à la cible du backend.

Notez que vous pouvez ajouter une autre instruction de débogage pour imprimer les données transformées à des fins de débogage. Exemple :

ondata_request: function(req, res, data, next) {
  debug('****** plugin ondata_request');
  var translated_data = parser.toJson(data);
  debug('****** plugin ondata_response: translated_json: ' + translated_json);
  next(null, translated_data);
},

À propos de l'ordre d'exécution du gestionnaire de plug-ins

Si vous écrivez des plug-ins pour Edge Microgateway, vous devez comprendre l'ordre dans lequel les gestionnaires d'événements de plug-in sont exécutés.

Souvenez-vous que lorsque vous spécifiez une séquence de plug-in dans le fichier de configuration Edge Microgateway, les gestionnaires de requêtes s'exécutent dans l'ordre croissant, tandis que les gestionnaires de réponses s'exécutent dans l'ordre décroissant.

L'exemple suivant est conçu pour vous aider à comprendre cette séquence d'exécution.

1. Créer trois plug-ins simples

Prenons l'exemple du plug-in suivant. Elle se contente de générer des résultats dans la console d'impression lorsque ses gestionnaires d'événements sont appelés:

plugins/plugin-1/index.js

module.exports.init = function(config, logger, stats) {

  return {

    onrequest: function(req, res, next) {
      console.log('plugin-1: onrequest');
      next();
    },

    onend_request: function(req, res, data, next) {
      console.log('plugin-1: onend_request');
      next(null, data);
    },

    ondata_response: function(req, res, data, next) {
      console.log('plugin-1: ondata_response ' + data.length);
      next(null, data);
    },

    onend_response: function(req, res, data, next) {
      console.log('plugin-1: onend_response');
      next(null, data);
    }
  };
}

À présent, envisagez de créer deux autres plug-ins, plugin-2 et plugin-3, avec le même code (sauf en remplaçant les instructions console.log() par plugin-2 et plugin-3 respectivement).

2. Examiner le code du plug-in

Les fonctions de plug-in exportées dans <microgateway-root-dir>/plugins/plugin-1/index.js sont des gestionnaires d'événements qui s'exécutent à des moments spécifiques lors du traitement des requêtes et des réponses. Par exemple, onrequest exécute le premier octet des en-têtes de requête reçus. Alors que onend_response s'exécute après la réception du dernier octet des données de réponse.

Examinez le gestionnaire ondata_response. Il est appelé chaque fois qu'un fragment de données de réponse est reçu. Il est important de savoir que les données de réponse ne sont pas nécessairement reçues en même temps. Les données peuvent plutôt être reçues par blocs de longueur arbitraire.

3. Ajoutez les plug-ins à la séquence de plug-ins

Pour poursuivre avec cet exemple, nous allons ajouter les plug-ins à la séquence de plug-ins dans le fichier de configuration Edge Microgateway (~./edgemicro/config.yaml) comme suit. La séquence est importante. Il définit l'ordre d'exécution des gestionnaires de plug-ins.

  plugins:
    dir: ../plugins
    sequence:
      - plugin-1
      - plugin-2
      - plugin-3
  

4. Examiner le résultat du débogage

Examinons maintenant la sortie qui serait générée lorsque ces plug-ins seraient appelés. Voici quelques points importants à noter:

  • La séquence du plug-in du fichier de configuration Edge Microgateway (~./edgemicro/config.yaml) spécifie l'ordre dans lequel les gestionnaires d'événements sont appelés.
  • Les gestionnaires de requêtes sont appelés dans l'ordre croissant (ordre dans lequel ils apparaissent dans la séquence du plug-in : 1, 2, 3).
  • Les gestionnaires de réponses sont appelés dans l'ordre décroissant : 3, 2, 1.
  • Le gestionnaire ondata_response est appelé une fois pour chaque fragment de données reçu. Dans cet exemple (résultat illustré ci-dessous), deux fragments sont reçus.

Voici un exemple de sortie de débogage générée lorsque ces trois plug-ins sont utilisés et qu'une requête est envoyée via Edge Microgateway. Notez simplement l'ordre dans lequel les gestionnaires sont appelés:

  plugin-1: onrequest
  plugin-2: onrequest
  plugin-3: onrequest

  plugin-1: onend_request
  plugin-2: onend_request
  plugin-3: onend_request

  plugin-3: ondata_response 931
  plugin-2: ondata_response 931
  plugin-1: ondata_response 931

  plugin-3: ondata_response 1808
  plugin-3: onend_response

  plugin-2: ondata_response 1808
  plugin-2: onend_response

  plugin-1: ondata_response 1808
  plugin-1: onend_response

Résumé

Il est très important de comprendre l'ordre dans lequel les gestionnaires de plug-ins sont appelés lorsque vous essayez de mettre en œuvre des fonctionnalités de plug-in personnalisées, telles que l'accumulation et la transformation des données de requête ou de réponse.

N'oubliez pas que les gestionnaires de requêtes sont exécutés dans l'ordre dans lequel les plug-ins sont spécifiés dans le fichier de configuration Edge Microgateway et que les gestionnaires de réponses sont exécutés dans l'ordre inverse.

À propos de l'utilisation de variables globales dans les plug-ins

Chaque requête envoyée à Edge Microgateway est envoyée à la même instance d'un plug-in. Par conséquent, l'état d'une deuxième requête d'un autre client écrasera le premier. Le seul endroit sûr pour enregistrer l'état du plug-in est de le stocker dans une propriété de l'objet de requête ou de réponse (dont la durée de vie est limitée à celle de la requête).

Réécrire les URL cibles dans les plug-ins

Ajoutée dans: v2.3.3

Vous pouvez remplacer l'URL cible par défaut dans un plug-in de manière dynamique en modifiant ces variables dans le code de votre plug-in: req.targetHostname et req.targetPath.

Ajoutée dans: v2.4.x

Vous pouvez également ignorer le port du point de terminaison cible et choisir entre HTTP et HTTPS. Modifiez les variables suivantes dans le code de votre plug-in: req.targetPort et req.targetSecure. Pour choisir HTTPS, définissez req.targetSecure sur true. Pour HTTP, définissez-le sur false. Si vous définissez req.targetSecure sur "true", consultez ce fil de discussion pour plus d'informations.

Supprimé dans: v3.3.3

L'exemple de plug-in appelé eurekaclient a été supprimé d'Edge Microgateway dans la version 3.3.3. Consultez les notes de version.

La suppression de cette fonctionnalité n'affecte pas la fonctionnalité de base de la microgateway ni la réécriture des URL cibles. Vous pouvez configurer la recherche dynamique des points de terminaison et remplacer les variables cibles telles que req.targetHostname, req.targetPath, req.targetPort et req.targetSecure au niveau du plug-in. Consultez la page Réécrire les URL cibles dans les plug-ins.


Exemples de plug-ins

Ces plug-ins sont fournis avec votre installation Edge Microgateway. Vous les trouverez dans l'installation d'Edge Microgateway ici:

[prefix]/lib/node_modules/edgemicro/plugins

[prefix] est le répertoire de préfixe npm, comme décrit dans la section "Où Edge Microgateway est-elle installée ?" de la section Installer Edge Microgateway.

cumul-request

Ce plug-in accumule des fragments de données du client dans une propriété de tableau associée à l'objet de requête. Lorsque toutes les données de requête sont reçues, le tableau est concaténé dans un tampon, qui est ensuite transmis au plug-in suivant de la séquence. Ce plug-in doit être le premier plug-in de la séquence afin que les plug-ins suivants reçoivent les données de requête accumulées.

module.exports.init = function(config, logger, stats) {

  function accumulate(req, data) {

    if (!req._chunks) req._chunks = [];
    req._chunks.push(data);

  }

  return {

    ondata_request: function(req, res, data, next) {

      if (data && data.length > 0) accumulate(req, data);

      next(null, null);

    },


    onend_request: function(req, res, data, next) {

      if (data && data.length > 0) accumulate(req, data);

      var content = null;

      if (req._chunks && req._chunks.length) {

        content = Buffer.concat(req._chunks);

      }

      delete req._chunks;

      next(null, content);

    }

  };

}

réponse-cumule

Ce plug-in accumule des fragments de données de la cible dans une propriété de tableau associée à l'objet de réponse. Lorsque toutes les données de réponse sont reçues, le tableau est concaténé dans un tampon, qui est ensuite transmis au plug-in suivant de la séquence. Étant donné que ce plug-in agit sur les réponses, qui sont traitées dans l'ordre inverse, vous devez le positionner comme dernier plug-in de la séquence.

module.exports.init = function(config, logger, stats) {

  function accumulate(res, data) {
    if (!res._chunks) res._chunks = [];
    res._chunks.push(data);
  }

  return {

    ondata_response: function(req, res, data, next) {
      if (data && data.length > 0) accumulate(res, data);
      next(null, null);
    },

    onend_response: function(req, res, data, next) {
      if (data && data.length > 0) accumulate(res, data);
      var content = Buffer.concat(res._chunks);
      delete res._chunks;
      next(null, content);
    }

  };

}

Plug-in "header-uppercase"

Les distributions Edge Microgateway incluent un exemple de plug-in appelé <microgateway-root-dir>/plugins/header-uppercase. L'exemple inclut des commentaires décrivant chacun des gestionnaires de fonctions. Cet exemple effectue une transformation simple des données de la réponse cible, et ajoute des en-têtes personnalisés à la requête du client et à la réponse cible.

Voici le code source de <microgateway-root-dir>/plugins/header-uppercase/index.js:

'use strict';

var debug = require('debug')('plugin:header-uppercase');

// required
module.exports.init = function(config, logger, stats) {

  var counter = 0;

  return {

    // indicates start of client request
    // request headers, url, query params, method should be available at this time
    // request processing stops (and a target request is not initiated) if
    // next is called with a truthy first argument (an instance of Error, for example)
    onrequest: function(req, res, next) {
      debug('plugin onrequest');
      req.headers['x-foo-request-id'] = counter++;
      req.headers['x-foo-request-start'] = Date.now();
      next();
    },

    // indicates start of target response
    // response headers and status code should be available at this time
    onresponse: function(req, res, next) {
      debug('plugin onresponse');
      res.setHeader('x-foo-response-id', req.headers['x-foo-request-id']);
      res.setHeader('x-foo-response-time', Date.now() - req.headers['x-foo-request-start']);
      next();
    },

    // chunk of request body data received from client
    // should return (potentially) transformed data for next plugin in chain
    // the returned value from the last plugin in the chain is written to the target
    ondata_request: function(req, res, data, next) {
      debug('plugin ondata_request ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    },

    // chunk of response body data received from target
    // should return (potentially) transformed data for next plugin in chain
    // the returned value from the last plugin in the chain is written to the client
    ondata_response: function(req, res, data, next) {
      debug('plugin ondata_response ' + data.length);
      var transformed = data.toString().toUpperCase();
      next(null, transformed);
    },

    // indicates end of client request
    onend_request: function(req, res, data, next) {
      debug('plugin onend_request');
      next(null, data);
    },

    // indicates end of target response
    onend_response: function(req, res, data, next) {
      debug('plugin onend_response');
      next(null, data);
    },

    // error receiving client request
    onerror_request: function(req, res, err, next) {
      debug('plugin onerror_request ' + err);
      next();
    },

    // error receiving target response
    onerror_response: function(req, res, err, next) {
      debug('plugin onerror_response ' + err);
      next();
    },

    // indicates client connection closed
    onclose_request: function(req, res, next) {
      debug('plugin onclose_request');
      next();
    },

    // indicates target connection closed
    onclose_response: function(req, res, next) {
      debug('plugin onclose_response');
      next();
    }

  };

}


transformer-majuscule

Il s'agit d'un plug-in de transformation général que vous pouvez modifier pour effectuer le type de transformation de votre choix. Cet exemple transforme simplement les données de réponse et de requête en majuscules.

 */
module.exports.init = function(config, logger, stats) {

  // perform content transformation here
  // the result of the transformation must be another Buffer
  function transform(data) {
    return new Buffer(data.toString().toUpperCase());
  }

  return {

    ondata_response: function(req, res, data, next) {
      // transform each chunk as it is received
      next(null, data ? transform(data) : null);
    },

    onend_response: function(req, res, data, next) {
      // transform accumulated data, if any
      next(null, data ? transform(data) : null);
    },

    ondata_request: function(req, res, data, next) {
      // transform each chunk as it is received
      next(null, data ? transform(data) : null);
    },

    onend_request: function(req, res, data, next) {
      // transform accumulated data, if any
      next(null, data ? transform(data) : null);
    }

  };

}