Vous consultez la documentation Apigee Edge.
Accédez à la documentation Apigee X.
Edge Microgateway v. 3.3.x
Audience
Cette section s'adresse 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 avoir de l'expérience avec 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-in suivent un modèle cohérent et sont stockés dans un emplacement connu d'Edge Microgateway, ce qui leur permet d'être détectés et exécutés automatiquement. Plusieurs plug-ins prédéfinis sont fournis lorsque vous installez Edge Microgateway. Il s'agit, entre autres, de plug-ins pour l'authentification, l'arrêt des pics, les quotas et les analyses. Ces plug-ins existants sont décrits dans Utiliser des plug-ins.
Vous pouvez ajouter de nouvelles fonctionnalités au microgateway en écrivant des plug-ins personnalisés. Par défaut, Edge Microgateway est essentiellement un proxy sécurisé qui transmet les requêtes et les réponses sans les modifier vers et depuis les services cibles. Les plug-ins personnalisés vous permettent d'interagir de manière programmatique avec les requêtes et les réponses qui transitent par la micro-passerelle.
Où placer le code du plug-in personnalisé
Un dossier pour les plug-ins personnalisés est inclus dans l'installation d'Edge Microgateway :
[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins
où [prefix] correspond au répertoire de préfixe npm, comme décrit dans "Où Edge Microgateway est-il installé ?" dans Installer Edge Microgateway.
Vous pouvez modifier ce répertoire de plug-ins par défaut. Consultez Où trouver les plug-ins.
Examiner les plug-ins prédéfinis
Avant d'essayer de développer votre propre plug-in, vérifiez qu'aucun des plug-ins prédéfinis ne répond à vos besoins. Ces plug-ins se trouvent dans :
[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins
où [prefix] est le répertoire de préfixe npm. Consultez également "Où Edge Microgateway est-il installé ?" dans Installer Edge Microgateway.
Pour en savoir plus, consultez également 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 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 l'affiche dans le terminal.
- Si Edge Microgateway est en cours d'exécution, arrêtez-le maintenant :
edgemicro stop
-
cddans le répertoire de plug-ins personnalisés :cd [prefix]/lib/node_modules/edgemicro/pluginsoù
[prefix]correspond au répertoire de préfixenpm, comme décrit dans "Où Edge Microgateway est-il installé ?" dans Installer Edge Microgateway. - Créez un projet de plug-in nommé response-override et
cdpour y accéder :
mkdir response-override && cd response-override
- Créez un projet Node.js :
Appuyez plusieurs fois sur "Entrée" pour accepter les valeurs par défaut.npm init
- Utilisez un éditeur de texte pour créer un fichier nommé
index.js. - 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"); } }; }
- Maintenant que vous avez créé un plug-in, vous devez l'ajouter à la configuration Edge Microgateway.
Ouvrez le fichier
$HOME/.edgemicro/[org]-[env]-config.yaml, oùorgetenvsont les noms de votre organisation et de votre environnement Edge. - Ajoutez le plug-in
response-overrideà l'élémentplugins:sequence, comme indiqué ci-dessous.
... plugins: dir: ../plugins sequence: - oauth - response-override ... - Redémarrez Edge Microgateway.
- Appelez une API via Edge Microgateway. (Cet appel d'API suppose que vous avez configuré la même configuration que le tutoriel avec la sécurité des clés API, comme décrit dans Configurer et 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 lorsque vous développez vos propres plug-ins. Le code source de l'exemple de plug-in abordé dans cette section se trouve dans plugins/header-uppercase/index.js..
- Les plug-ins sont des modules NPM standards avec un fichier
package.jsonetindex.jsdans le dossier racine. - Un plug-in doit exporter une fonction init().
- La fonction init() accepte 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 pendant la durée de vie 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. L'implémentation de ces fonctions vous incombe. Toute fonction donnée est facultative, et un plug-in typique implémentera au moins un sous-ensemble de ces fonctions.
Gestionnaires d'événements de flux de requête
Ces fonctions sont appelées lors d'événements de requête dans Edge Microgateway.
onrequestondata_requestonend_requestonclose_requestonerror_request
onrequest function
Appelé 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 "truthy" (par exemple, 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(); }
ondata_request function
Appelée lorsqu'un bloc de données est reçu du client. Transmet les données de la requête au prochain plug-in de 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, illustré 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); }
onend_request function
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 a été 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é en cas d'erreur de réception de la demande 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 les événements de réponse dans Edge Microgateway.
onresponseondata_responseonend_responseonclose_responseonerror_response
Fonction onresponse
Appelé 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 bloc 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 a été fermée. Vous pouvez utiliser cette fonction lorsque la connexion cible n'est pas fiable. Il est appelé 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é en cas d'erreur de 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 de gestion des é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 lorsque Edge Microgateway traite une requête d'API donnée.
- Chacun des gestionnaires de fonction 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'arrête et la requête se bloque.
- Le premier argument de next() peut être une erreur qui entraînera 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 met 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 par requête entre les appels, il peut enregistrer cet état dans une propriété ajoutée à l'objet request (req) fourni, dont la durée de vie correspond à la durée de l'appel d'API.
- Veillez à détecter toutes les erreurs et à appeler next() avec l'erreur. Si vous n'appelez pas next(), l'appel d'API sera suspendu.
- Veillez à ne pas introduire de fuites de mémoire, car cela peut affecter les performances globales d'Edge Microgateway et entraîner son plantage s'il manque de mémoire.
- Veillez à suivre le modèle Node.js en n'effectuant pas de tâches gourmandes en 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 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, insérez ce qui suit dans le fichier default.yaml :
response-override:
param: fooVous 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, vous verrez "foo" s'afficher 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 fusionnée de Microgateway 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;
Voici 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
L'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 transitant par une instance de microgateway.
- treqErrors : nombre de requêtes cibles comportant des erreurs.
- treqErrors : 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 : 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 à traiter 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(). Toutefois, ondata_request n'est appelée que si la requête inclut des données, comme dans le cas d'une requête POST, par exemple. La prochaine méthode appelée sera onend_request(), qui est appelée lorsque le traitement de la requête est terminé. Les fonctions onerror_* ne sont appelées qu'en cas d'erreur. Elles vous permettent de gérer les erreurs 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 sur les erreurs, que vous pouvez ensuite gérer dans une fonction ultérieure de la chaîne. En définissant la valeur sur null, un argument "falsy", nous indiquons qu'il n'y a pas d'erreur et que le traitement des requêtes doit se dérouler normalement. Si cet argument est "truthy" (par exemple, un objet Error), le traitement de la requête s'arrête et la requête 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 avez la possibilité de modifier les données de la requête dans cette méthode et de 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) modifie le type de contenu de l'en-tête de la requête en application/json et convertit les données de la requête en JSON à l'aide de la méthode de votre choix (par exemple, vous pouvez utiliser un convertisseur xml2json Node.js obtenu à partir de NPM).
Voici un exemple :
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 supposé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 de 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 des gestionnaires 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-ins 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éez trois plug-ins simples
Prenons l'exemple du plug-in suivant. Il se contente d'imprimer la sortie de la console 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 que vous devez 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 s'exécute lorsque le premier octet des en-têtes de requête est reçu. Tandis que onend_response s'exécute après la réception du dernier octet des données de réponse.
Jetez un coup d'œil au gestionnaire ondata_response : il est appelé chaque fois qu'un bloc 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 une seule fois. Les données peuvent être reçues par blocs de longueur arbitraire.
3. Ajouter les plug-ins à la séquence de plug-ins
En continuant 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. L'ordre est important. Il définit l'ordre dans lequel les gestionnaires de plug-in s'exécutent.
plugins:
dir: ../plugins
sequence:
- plugin-1
- plugin-2
- plugin-3
4. Examiner la sortie de débogage
Examinons maintenant le résultat qui serait produit 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 (l'ordre dans lequel ils apparaissent dans la séquence de plug-ins : 1, 2, 3).
- Les gestionnaires de réponse sont appelés dans l'ordre décroissant : 3, 2, 1.
- Le gestionnaire
ondata_responseest appelé une fois pour chaque bloc de données qui arrive. Dans cet exemple (résultat affiché ci-dessous), deux blocs sont reçus.
Voici un exemple de résultat de débogage produit 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-in sont appelés lorsque vous essayez d'implémenter une fonctionnalité de plug-in personnalisée, comme 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 provenant 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é dans la version 2.3.3
Vous pouvez remplacer l'URL cible par défaut dans un plug-in de manière dynamique en modifiant les variables req.targetHostname et req.targetPath dans le code de votre plug-in.
Ajouté dans la version 2.4.x
Vous pouvez également remplacer 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.
Supprimé dans la version 3.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 d'Edge Microgateway ni la réécriture des URL cibles. Vous pouvez configurer la recherche dynamique de 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 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 :
[prefix]/lib/node_modules/edgemicro/plugins
où [prefix] correspond au répertoire de préfixe npm, comme décrit dans "Où Edge Microgateway est-il installé ?" dans Installer Edge Microgateway.
accumulate-request
Ce plug-in accumule les blocs de données du client dans une propriété de tableau associée à l'objet de requête. Une fois toutes les données de la requête 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 de la séquence afin que les plug-ins suivants reçoivent les données de requête cumulé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); } }; }
accumulate-response
Ce plug-in accumule les blocs de données de la cible dans une propriété de tableau associée à l'objet de réponse. Une fois toutes les données de réponse 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 fonctionne sur les réponses, qui sont traitées dans l'ordre inverse, vous devez le placer en dernier dans 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 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(); } }; }
transform-uppercase
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); } }; }