Développer des plug-ins personnalisés

Vous consultez la documentation d'Apigee Edge.
Consultez la documentation 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, vous devez savoir utiliser JavaScript et Node.js.

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écouvrir et de les exécuter automatiquement. Plusieurs plug-ins prédéfinis sont fournis lorsque vous installez Edge Microgateway. Ceux-ci 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 micropasserelle en écrivant des plug-ins personnalisés. Par défaut, Edge Microgateway est essentiellement un proxy passthrough sécurisé qui transmet les requêtes et les réponses telles quelles aux services cibles et à ceux-ci. Avec les plug-ins personnalisés, vous pouvez interagir de manière automatisée avec les requêtes et les réponses qui transitent par la micropasserelle.

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

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

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

[prefix] correspond au 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 bon de vérifier qu'aucun des plug-ins prédéfinis ne répond à vos besoins. 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 nécessaires à la création d'un plug-in simple. Ce plug-in remplace les données de réponse (quelles qu'elles soient) avec la chaîne "Hello, World!" et les affiche sur le terminal.

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

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

    [prefix] correspond au 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 y ajoutez 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. (Cet appel d'API suppose 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 la section 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 les éléments package.json et index.js.
  • Un plug-in doit exporter une fonction init().
  • La fonction init() utilise trois arguments: config, logger et stats. Ces arguments sont décrits dans les 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 de 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. Toutes les fonctions sont facultatives, 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 de vérité (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 du client est fermée. Vous pouvez utiliser cette fonction lorsque la connexion client n'est pas fiable. Il est appelé lorsque la connexion de 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. Il est appelé lorsque la connexion de 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 qu'il faut savoir sur les fonctions du gestionnaire d'événements de plug-in

Les fonctions de 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 est en mémoire tampon et ne dispose pas de suffisamment de données à transformer pour le moment.
  • Notez qu'une seule instance du plug-in est utilisée pour traiter toutes les requêtes et réponses. Si un plug-in souhaite conserver l'état de chaque 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 correspondante. L'échec de l'appel de next() entraîne la suspension de l'appel d'API.
  • Veillez à ne pas introduire de fuites de mémoire, car elles pourraient affecter les performances globales d'Edge Microgateway et entraîner son plantage 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 nuire aux 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 à partir d'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 cet élément 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 suit:

// 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 emgConfigs contient:

{
    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 contenant 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 micropasserelle.

  • treqErrors : le nombre de requêtes cibles comportant des erreurs.
  • treqErrors : le nombre de réponses cibles comportant des erreurs.
  • statusCodes – 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 ondata_request() est ensuite appelée. Cependant, ondata_request n'est appelé que si la requête inclut des données, comme dans le cas d'une requête POST, par exemple. La méthode suivante appelée est 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. Si vous le souhaitez, elles vous permettent de gérer les erreurs avec du code personnalisé.

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 sur les erreurs, que vous pouvez ensuite gérer dans une fonction ultérieure de la chaîne. En le définissant sur null, un argument incorrect, nous disons qu'il n'y a pas d'erreur et le traitement de la requête doit se dérouler normalement. Si cet argument est fiable (objet Erreur, par exemple), 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. En l'absence de 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 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 la requête au format JSON selon ce que vous voulez (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 au format 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.

Il est important de se rappeler 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 d'afficher la sortie de 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);
    }
  };
}

Envisagez maintenant de créer deux autres plug-ins, plugin-2 et plugin-3, avec le même code (sauf que vous pouvez remplacer 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çu. 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 toutes en même temps. Les données peuvent plutôt être reçues par fragments de longueur arbitraire.

3. Ajouter 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 la sortie de débogage

Examinons maintenant le résultat qui est généré lorsque ces plug-ins sont appelés. Voici quelques points importants à noter:

  • La séquence de plug-ins 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 de plug-ins : 1, 2, 3).
  • Les gestionnaires de réponses sont appelés par 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 (sortie ci-dessous), deux fragments sont reçus.

Voici un exemple de résultat de débogage généré 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 une fonctionnalité de plug-in personnalisée, telle 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 consiste à 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 ces variables 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 en savoir plus.

Un exemple de plug-in appelé eurekaclient a été ajouté à Edge Microgateway. Ce plug-in montre comment utiliser les variables req.targetPort et req.targetSecure, et comment Edge Microgateway peut effectuer une recherche dynamique de points de terminaison à l'aide d'Eureka en tant que catalogue de points de terminaison de service.


Exemples de plug-ins

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

[prefix]/lib/node_modules/edgemicro/plugins

[prefix] correspond au 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 la 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 dans la séquence pour 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-cumulée

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 des réponses traitées dans l'ordre inverse, vous devez le placer 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 la réponse et les données de la 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);
    }

  };

}