Sviluppa plug-in personalizzati

Stai visualizzando la documentazione di Apigee Edge.
Vai alla documentazione di Apigee X.
informazioni

Edge Microgateway 3.1.5 e versioni successive

Pubblico

Questo argomento è rivolto agli sviluppatori che vogliono estendere le funzionalità di Edge Microgateway scrivendo plug-in personalizzati. Se vuoi scrivere un nuovo plug-in, è necessaria l'esperienza con JavaScript e Node.js.

Che cos'è un plug-in Edge Microgateway personalizzato?

Un plug-in è un modulo Node.js che aggiunge funzionalità a Edge Microgateway. I moduli plug-in seguono un pattern coerente e vengono memorizzati in una posizione nota a Edge Microgateway, in modo da poter essere rilevati ed eseguiti automaticamente. Durante l'installazione di Edge Microgateway, vengono forniti diversi plug-in predefiniti. Questi includono plug-in per autenticazione, arresto dei picchi di traffico, quota e analisi. Questi plug-in esistenti sono descritti nella sezione Utilizzare i plug-in.

Puoi aggiungere nuove caratteristiche e caratteristiche al microgateway scrivendo plug-in personalizzati. Per impostazione predefinita, Edge Microgateway è essenzialmente un proxy passthrough sicuro che passa richieste e risposte invariate da e verso i servizi di destinazione. Con i plug-in personalizzati, puoi interagire in modo programmatico con le richieste e le risposte che passano attraverso il microgateway.

Dove inserire il codice plug-in personalizzato

Qui è inclusa una cartella per i plug-in personalizzati nell'installazione di Edge Microgateway:

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

dove [prefix] è la directory del prefisso npm, come descritto in "Dove è installato Edge Microgateway" in Installazione di Edge Microgateway.

Puoi modificare questa directory predefinita dei plug-in. Consulta la sezione Dove trovare i plug-in.

Esame dei plug-in predefiniti

Prima di provare a sviluppare un plug-in, è bene verificare che nessuno dei plug-in predefiniti soddisfi i requisiti. Questi plug-in si trovano in:

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

dove [prefix] è la directory del prefisso npm. Vedi anche "Dove è installato Edge Microgateway" in Installazione di Edge Microgateway.

Per maggiori dettagli, consulta anche Plug-in predefiniti forniti con Edge Microgateway.

Scrivi un plug-in semplice

In questa sezione vengono illustrati i passaggi necessari per creare un plug-in semplice. Questo plug-in sostituisce i dati della risposta (qualunque siano) con la stringa "Hello, World!" e li stampa nel terminale.

  1. Se Edge Microgateway è in esecuzione, interrompilo ora:
    edgemicro stop
    
  2. cd alla directory dei plug-in personalizzati:

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

    dove [prefix] è la directory del prefisso npm, come descritto in "Where is Edge Microgateway installato" in Installazione di Edge Microgateway.

  3. Crea un nuovo progetto plug-in denominato response-override e cd:
    mkdir response-override && cd response-override
    
  4. Crea un nuovo progetto Node.js:
    npm init
    
    Premi più volte per accettare i valori predefiniti.
  5. Utilizza un editor di testo per creare un nuovo file denominato index.js.
  6. Copia il seguente codice in index.js e salva il file.
    '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. Ora che hai creato un plug-in, devi aggiungerlo alla configurazione di Edge Microgateway. Apri il file $HOME/.edgemicro/[org]-[env]-config.yaml, dove org e env sono i nomi delle organizzazioni e degli ambienti Edge.
  8. Aggiungi il plug-in response-override all'elemento plugins:sequence come mostrato di seguito.
          ...
          
          plugins:
            dir: ../plugins
            sequence:
              - oauth
              - response-override
              
          ...
    
  9. Riavvia Edge Microgateway.
  10. Chiama un'API tramite Edge Microgateway. Questa chiamata API presuppone che tu abbia impostato la stessa configurazione del tutorial con la sicurezza delle chiavi API, come descritto in Configurare e configurare Edge Microgateway:
    curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo
    Hello, World!
    

Struttura di un plug-in

Il seguente plug-in di esempio Edge Microgateway illustra il pattern da seguire durante lo sviluppo dei tuoi plug-in. Il codice sorgente del plug-in di esempio discusso in questa sezione è in plugins/header-uppercase/index.js.

  • I plug-in sono moduli NPM standard con package.json e index.js nella cartella principale.
  • Un plug-in deve esportare una funzione init().
  • La funzione init() utilizza tre argomenti: config, logger e stats. Questi argomenti sono descritti negli argomenti della funzione init() del plug-in.
  • init() restituisce un oggetto con gestori di funzioni con nome che vengono chiamati quando si verificano determinati eventi durante il ciclo di vita di una richiesta.

Funzioni gestore eventi

Un plug-in deve implementare alcune o tutte queste funzioni di gestore di eventi. L'implementazione di queste funzioni spetta a te. Ogni funzione specificata è facoltativa e un plug-in tipico implementa almeno un sottoinsieme di queste funzioni.

Gestori di eventi del flusso di richieste

Queste funzioni vengono richiamate sugli eventi di richiesta in Edge Microgateway.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

onrequest funzione

Chiamato all'inizio della richiesta del client. Questa funzione viene attivata quando il primo byte della richiesta viene ricevuto da Edge Microgateway. Questa funzione consente di accedere alle intestazioni delle richieste, all'URL, ai parametri di ricerca e al metodo HTTP. Se chiami successivo con un primo argomento attendibile (come un'istanza di errore), l'elaborazione della richiesta si interrompe e la richiesta di destinazione non viene avviata.

Esempio:

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

ondata_request funzione

Richiamato quando viene ricevuto un blocco di dati dal client. Trasferisce i dati della richiesta al plug-in successivo nella sequenza del plug-in. Il valore restituito dall'ultimo plug-in della sequenza viene inviato alla destinazione. Un caso d'uso tipico, mostrato di seguito, consiste nel trasformare i dati delle richieste prima di inviarli alla destinazione.

Esempio:

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

onend_request funzione

Richiamato quando tutti i dati della richiesta sono stati ricevuti dal client.

Esempio:

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

Funzione onclose_request

Indica che la connessione client è stata chiusa. Puoi utilizzare questa funzione nei casi in cui la connessione client non è affidabile. Viene chiamato quando la connessione socket al client è chiusa.

Esempio:

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

Funzione onerror_request

Richiamato se si verifica un errore nella ricezione della richiesta del client.

Esempio:

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

Gestori di eventi del flusso di risposta

Queste funzioni vengono richiamate durante gli eventi di risposta in Edge Microgateway.

  • onresponse
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

Funzione onresponse

Chiamata all'inizio della risposta target. Questa funzione viene attivata quando il primo byte della risposta viene ricevuto da Edge Microgateway. Questa funzione consente di accedere alle intestazioni delle risposte e al codice di stato.

Esempio:

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


Funzione ondata_response

Richiamato quando riceve un blocco di dati dalla destinazione.

Esempio:

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


Funzione onend_response

Richiamato quando tutti i dati di risposta sono stati ricevuti dalla destinazione.

Esempio:

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

Funzione onclose_response

Indica che la connessione di destinazione è stata chiusa. Puoi utilizzare questa funzione nei casi in cui la connessione di destinazione non è affidabile. Viene chiamato quando la connessione socket alla destinazione è chiusa.

Esempio:

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


Funzione onerror_response

Richiamato se si verifica un errore di ricezione della risposta target.

Esempio:

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

Cosa devi sapere sulle funzioni del gestore di eventi dei plug-in

Le funzioni del gestore di eventi dei plug-in vengono richiamate in risposta a eventi specifici che si verificano mentre Edge Microgateway elabora una determinata richiesta API.

  • Ciascun gestore delle funzioni init() (ondata_request, ondata_response e così via) deve chiamare il callback next() al termine dell'elaborazione. Se non chiami next(), l'elaborazione verrà interrotta e la richiesta verrà bloccata.
  • Il primo argomento di next() potrebbe essere un errore che determina l'interruzione dell'elaborazione delle richieste.
  • I gestori ondata_ e onend_ devono chiamare next() con un secondo argomento contenente i dati da passare al target o al client. Questo argomento può essere nullo se il plug-in esegue il buffering e non dispone di dati sufficienti per la trasformazione al momento.
  • Tieni presente che viene utilizzata una singola istanza del plug-in per gestire tutte le richieste e risposte. Se un plug-in vuole conservare lo stato a livello di richiesta tra una chiamata e l'altra, può salvarlo in una proprietà aggiunta all'oggetto request (req) fornito, la cui durata corrisponde alla durata della chiamata API.
  • Cerca di individuare tutti gli errori e chiama next() con l'errore. La mancata chiamata di next() comporterà il blocco della chiamata API.
  • Fai attenzione a non introdurre perdite di memoria, che possono influire sulle prestazioni complessive di Edge Microgateway e causarne l'arresto anomalo se esaurisce la memoria.
  • Fai attenzione a seguire il modello Node.js non eseguendo attività ad alta intensità di calcolo nel thread principale, poiché ciò può influire negativamente sulle prestazioni di Edge Microgateway.

Informazioni sulla funzione init() del plug-in

Questa sezione descrive gli argomenti passati alla funzione init(): config, logger e stats.

config

I dati di configurazione ottenuti mediante l'unione del file di configurazione di Edge Microgateway con i dati scaricati da Apigee Edge vengono inseriti in un oggetto denominato: config.

Per aggiungere un parametro di configurazione denominato param con valore foo a un plug-in chiamato response-override, inserisci quanto segue nel file default.yaml:

response-override:
    param: foo

Successivamente, puoi accedere al parametro nel codice plug-in in questo modo:

// 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);
    },

In questo caso, vedrai foo stampato nell'output di debug del plug-in:

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

Puoi accedere alla configurazione del microgateway unita e scaricare i dati Apigee Edge nell'oggetto secondario config.emgConfigs. Ad esempio, puoi accedere a questi dati di configurazione nella funzione init come segue:

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

Di seguito è riportato un esempio di dati che contengono 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

Il logger di sistema. Il logger attualmente utilizzato esporta queste funzioni, dove l'oggetto può essere una stringa, una richiesta HTTP, una risposta HTTP o un'istanza di errore.

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

stats

Un oggetto che contiene i conteggi di richieste, risposte, errori e altre statistiche aggregate relative alle richieste e alle risposte che passano attraverso un'istanza microgateway.

  • treqErrors: il numero di richieste target con errori.
  • treqErrors: il numero di risposte target con errori.
  • statusCodes: un oggetto che contiene il codice di risposta:
{
  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
  }
  
  • richieste: il numero totale di richieste.
  • risposte - Il numero totale di risposte.
  • connections: il numero di connessioni di destinazione attive.

Informazioni sulla funzione next()

Tutti i metodi del plug-in devono chiamare next() per continuare a elaborare il metodo successivo nella serie (in caso contrario il processo del plug-in si blocca). Nel ciclo di vita della richiesta, il primo metodo chiamato è onrequest(). Il successivo metodo da chiamare è il metodo ondata_request(); tuttavia, ondata_request viene chiamato solo se la richiesta include dati, come nel caso, ad esempio, di una richiesta POST. Il prossimo metodo chiamato sarà onend_request(), che viene richiamato al termine dell'elaborazione della richiesta. Le funzioni onerror_* vengono richiamate solo in caso di errore e ti consentono di gestire gli errori con codice personalizzato, se vuoi.

Supponiamo che nella richiesta vengano inviati dati e che venga chiamato ondata_request(). Nota che la funzione chiama next() con due parametri:

next(null, data);

Per convenzione, il primo parametro viene utilizzato per trasmettere informazioni sull'errore, che potrai poi gestire in una funzione successiva della catena. Impostandolo su null, un argomento fasullo, diciamo che non sono presenti errori e l'elaborazione delle richieste dovrebbe procedere normalmente. Se questo argomento è veritiero (ad esempio un oggetto Error), l'elaborazione della richiesta si interrompe e la richiesta viene inviata alla destinazione.

Il secondo parametro passa i dati della richiesta alla funzione successiva nella catena. Se non esegui alcuna elaborazione aggiuntiva, i dati della richiesta vengono passati senza modifiche alla destinazione dell'API. Tuttavia, hai la possibilità di modificare i dati della richiesta all'interno di questo metodo e trasmettere la richiesta modificata al target. Ad esempio, se i dati della richiesta sono XML e la destinazione prevede JSON, puoi aggiungere al metodo ondata_request() codice che (a) cambia il Content-Type dell'intestazione della richiesta in application/json e converte i dati della richiesta in JSON utilizzando il metodo che preferisci (ad esempio, puoi utilizzare un convertitore Node.js xml2json ottenuto da NPM).

Vediamo come potrebbe essere:

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

In questo caso, i dati della richiesta (presunti come XML) vengono convertiti in JSON e i dati trasformati vengono passati tramite next() alla funzione successiva nella catena di richieste, prima di essere passati alla destinazione del backend.

Tieni presente che potresti aggiungere un'altra istruzione di debug per stampare i dati trasformati a scopo di debug. Ad esempio:

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);
},

Informazioni sull'ordine di esecuzione del gestore dei plug-in

Se scrivi plug-in per Edge Microgateway, devi comprendere l'ordine in cui vengono eseguiti i gestori di eventi dei plug-in.

La cosa importante da ricordare è che quando specifichi una sequenza di plug-in nel file di configurazione di Edge Microgateway, i gestori di richieste vengono eseguiti in ordine crescente, mentre quelli delle risposte vengono eseguiti in ordine discendente.

Il seguente esempio è pensato per aiutarti a comprendere questa sequenza di esecuzione.

1. Crea tre semplici plug-in

Prendi in considerazione il seguente plug-in. Tutto ciò che fa è l'output della console di stampa quando i relativi gestori di eventi sono chiamati:

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);
    }
  };
}

Ora valuta la possibilità di creare altri due plug-in, plugin-2 e plugin-3, con lo stesso codice (tranne nel caso in cui le istruzioni console.log() vengano modificate rispettivamente in plugin-2 e plugin-3).

2. Rivedi il codice plug-in

Le funzioni plug-in esportate in <microgateway-root-dir>/plugins/plugin-1/index.js sono gestori di eventi che vengono eseguiti in orari specifici durante l'elaborazione di richieste e risposte. Ad esempio, onrequest esegue il primo byte delle intestazioni delle richieste ricevute. Invece, onend_response viene eseguito dopo la ricezione dell'ultimo byte di dati di risposta.

Dai un'occhiata al gestore ondata_response, che viene chiamato ogni volta che viene ricevuto un blocco di dati di risposta. La cosa importante da sapere è che i dati sulle risposte non vengono necessariamente ricevuti tutti in una volta. Piuttosto, i dati possono essere ricevuti in blocchi di lunghezza arbitraria.

3. Aggiungi i plug-in alla sequenza di plug-in

Proseguendo con questo esempio, aggiungeremo i plug-in alla sequenza di plug-in nel file di configurazione Edge Microgateway (~./edgemicro/config.yaml), come indicato di seguito. La sequenza è importante. Definisce l'ordine in cui vengono eseguiti i gestori dei plug-in.

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

4. Esaminare l'output di debug

Ora diamo un'occhiata all'output che si otterrebbe quando vengono chiamati questi plug-in. Ecco alcuni aspetti importanti da notare:

  • La sequenza del plug-in del file di configurazione Edge Microgateway (~./edgemicro/config.yaml) specifica l'ordine in cui vengono chiamati i gestori di eventi.
  • I gestori delle richieste vengono chiamati in ordine crescente (l'ordine in cui vengono visualizzati nella sequenza dei plug-in: 1, 2, 3).
  • I gestori delle risposte vengono chiamati in ordine discendente: 3, 2, 1.
  • Il gestore ondata_response viene chiamato una volta per ogni blocco di dati arrivato. In questo esempio (output mostrato di seguito), vengono ricevuti due blocchi.

Di seguito è riportato un esempio di output di debug generato quando questi tre plug-in sono in uso e viene inviata una richiesta tramite Edge Microgateway. Nota l'ordine in cui vengono chiamati i gestori:

  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

Riepilogo

Comprendere l'ordine in cui i gestori dei plug-in vengono chiamati è molto importante quando cerchi di implementare funzionalità plug-in personalizzate, come l'accumulo e la trasformazione dei dati di richieste o risposte.

Tieni presente che i gestori di richieste vengono eseguiti nell'ordine in cui i plug-in sono specificati nel file di configurazione di Edge Microgateway, mentre i gestori delle risposte vengono eseguiti nell'ordine opposto.

Informazioni sull'utilizzo delle variabili globali nei plug-in

Ogni richiesta a Edge Microgateway viene inviata alla stessa istanza di un plug-in; pertanto, lo stato di una seconda richiesta da un altro client sovrascriverà il primo. L'unica posizione sicura in cui salvare lo stato del plug-in è archiviare lo stato in una proprietà nell'oggetto richiesta o risposta (la cui durata è limitata a quella della richiesta).

Riscrittura degli URL di destinazione nei plug-in

Aggiunto in: v2.3.3

Puoi eseguire l'override dell'URL di destinazione predefinito in un plug-in in modo dinamico modificando le seguenti variabili nel codice del plug-in: req.targetHostname e req.targetPath.

Aggiunto in: v2.4.x

Puoi anche eseguire l'override della porta dell'endpoint di destinazione e scegliere tra HTTP e HTTPS. Modifica queste variabili nel codice plug-in: req.targetPort e req.targetSecure. Per scegliere HTTPS, imposta req.targetSecure su true; per HTTP, impostalo su false. Se imposti req.targetSecure su true, consulta questo thread di discussione per ulteriori informazioni.

Un plug-in di esempio denominato eurekaclient è stato aggiunto a Edge Microgateway. Questo plug-in mostra come utilizzare le variabili req.targetPort e req.targetSecure e illustra in che modo Edge Microgateway può eseguire una ricerca dinamica degli endpoint utilizzando Eureka come catalogo degli endpoint di servizio.


Plug-in di esempio

Questi plug-in vengono forniti con l'installazione del Microgateway Edge. Puoi trovarli nell'installazione di Edge Microgateway qui:

[prefix]/lib/node_modules/edgemicro/plugins

dove [prefix] è la directory del prefisso npm, come descritto in "Dove è installato Edge Microgateway" in Installazione di Edge Microgateway.

richiesta-cumulativa

Questo plug-in accumula blocchi di dati dal client in una proprietà array collegata all'oggetto della richiesta. Quando vengono ricevuti tutti i dati della richiesta, l'array viene concatenato in un buffer, che viene quindi passato al plug-in successivo della sequenza. Questo plug-in dovrebbe essere il primo plug-in della sequenza, in modo che i plug-in successivi ricevano i dati delle richieste accumulati.

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);

    }

  };

}

cumula-risposta

Questo plug-in accumula blocchi di dati dal target in una proprietà array collegata all'oggetto risposta. Quando vengono ricevuti tutti i dati della risposta, l'array viene concatenato in un buffer, che viene quindi passato al plug-in successivo della sequenza. Poiché questo plug-in opera sulle risposte, che vengono elaborate in ordine inverso, devi posizionarlo come ultimo plug-in della sequenza.

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

Le distribuzioni Edge Microgateway includono un plug-in di esempio chiamato <microgateway-root-dir>/plugins/header-uppercase. L'esempio include commenti che descrivono ciascuno dei gestori delle funzioni. Questo esempio esegue alcune semplici trasformazioni dei dati della risposta di destinazione e aggiunge intestazioni personalizzate alla richiesta del client e alla risposta di destinazione.

Ecco il codice sorgente per <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();
    }

  };

}


trasforma-maiuscole

Si tratta di un plug-in di trasformazione generico che puoi modificare per effettuare qualsiasi tipo di trasformazione. Questo esempio trasforma semplicemente in lettere maiuscole i dati della risposta e della richiesta.

 */
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);
    }

  };

}