Sviluppa plug-in personalizzati

Stai visualizzando la documentazione di Apigee Edge.
Consulta la documentazione di Apigee X.
info

Edge Microgateway versione 3.1.5 e 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 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 archiviati in una posizione nota a Edge Microgateway, consentendo di rilevarli ed eseguirli automaticamente. Quando installi Edge Microgateway, vengono forniti diversi plug-in predefiniti. Questi includono plug-in per l'autenticazione, l'arresto dei picchi, la quota e l'analisi. Questi plug-in esistenti sono descritti in Utilizzare i plug-in.

Puoi aggiungere nuove funzionalità al microgateway scrivendo plug-in personalizzati. Per impostazione predefinita, Edge Microgateway è essenzialmente un proxy pass-through sicuro che trasmette richieste e risposte invariate ai servizi di destinazione e dai 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 del plug-in personalizzato

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

[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 dei plug-in predefinita. Consulta la sezione Dove trovare i plug-in.

Esaminare i plug-in predefiniti

Prima di provare a sviluppare un plug-in personalizzato, è consigliabile verificare che nessuno dei plug-in predefiniti soddisfi i tuoi 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 viene installato Edge Microgateway" in Installazione di Edge Microgateway.

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

Scrivere un plug-in semplice

In questa sezione, esamineremo i passaggi necessari per creare un plug-in semplice. Questo plug-in sovrascrive i dati di risposta (qualunque siano) con la stringa "Hello, World!" e la stampa sul terminale.

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

    cd [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.

  3. Crea un nuovo progetto di plug-in denominato response-override e cd:
    mkdir response-override && cd response-override
  4. Crea un nuovo progetto Node.js:
    npm init
    Premi Invio 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 dell'organizzazione e dell'ambiente 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 configurato la stessa configurazione del tutorial con la sicurezza della chiave API, come descritto in Configurazione di 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 di Edge Microgateway illustra il pattern da seguire durante lo sviluppo dei tuoi plug-in. Il codice sorgente del plug-in di esempio descritto in questa sezione si trova in plugins/header-uppercase/index.js..

  • I plug-in sono moduli NPM standard con package.json e index.js nella cartella radice.
  • Un plug-in deve esportare una funzione init().
  • La funzione init() accetta tre argomenti: config, logger e stats. Questi argomenti sono descritti negli argomenti della funzione Plugin init().
  • 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 del gestore di eventi

Un plug-in deve implementare alcune o tutte queste funzioni di gestione degli eventi. L'implementazione di queste funzioni dipende da te. Qualsiasi funzione è facoltativa e un plug-in tipico implementa almeno un sottoinsieme di queste funzioni.

Gestori di eventi del flusso di richiesta

Queste funzioni vengono chiamate in base agli eventi di richiesta in Edge Microgateway.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

Funzione onrequest

Chiamato all'inizio della richiesta del client. Questa funzione viene attivata quando Edge Microgateway riceve il primo byte della richiesta. Questa funzione consente di accedere alle intestazioni della richiesta, all'URL, ai parametri di ricerca e al metodo HTTP. Se chiami next con un primo argomento truthy (ad esempio un'istanza di Error), l'elaborazione della richiesta si interrompe e non viene avviata una richiesta di destinazione.

Esempio:

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

Funzione ondata_request

Chiamato quando viene ricevuto un blocco di dati dal client. Trasmette i dati della richiesta al plug-in successivo nella sequenza di plug-in. Il valore restituito dall'ultimo plug-in nella sequenza viene inviato alla destinazione. Un caso d'uso tipico, mostrato di seguito, consiste nel trasformare i dati della richiesta 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);
    }

Funzione onend_request

Chiamato 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 viene chiusa.

Esempio:

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

Funzione onerror_request

Chiamato se si verifica un errore durante la 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 chiamate in base agli eventi di risposta in Edge Microgateway.

  • onresponse
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

Funzione onresponse

Chiamato all'inizio della risposta del target. Questa funzione viene attivata quando Edge Microgateway riceve il primo byte della risposta. Questa funzione ti consente di accedere alle intestazioni della risposta 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

Chiamato quando viene ricevuto 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

Chiamato quando tutti i dati di risposta sono stati ricevuti dal target.

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 viene chiusa.

Esempio:

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


Funzione onerror_response

Chiamato se si verifica un errore durante la ricezione della risposta di destinazione.

Esempio:

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

Informazioni importanti sulle funzioni di gestione degli eventi dei plug-in

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

  • Ciascuno dei gestori di funzioni init() (ondata_request, ondata_response e così via) deve chiamare il callback next() al termine dell'elaborazione. Se non chiami next(), l'elaborazione si interromperà e la richiesta rimarrà in sospeso.
  • Il primo argomento di next() può essere un errore che causerà l'interruzione dell'elaborazione della richiesta.
  • I gestori ondata_ e onend_ devono chiamare next() con un secondo argomento contenente i dati da passare alla destinazione o al client. Questo argomento può essere nullo se il plug-in sta memorizzando nel buffer e al momento non dispone di dati sufficienti per la trasformazione.
  • Tieni presente che viene utilizzata una sola istanza del plug-in per gestire tutte le richieste e le risposte. Se un plug-in vuole conservare lo stato per richiesta tra le chiamate, può salvarlo in una proprietà aggiunta all'oggetto request (req) fornito, la cui durata è la durata della chiamata API.
  • Fai attenzione a rilevare tutti gli errori e chiama next() con l'errore. Se non viene chiamato next(), la chiamata API si bloccherà.
  • Fai attenzione a non introdurre perdite di memoria, in quanto possono influire sulle prestazioni complessive di Edge Microgateway e causarne l'arresto anomalo se la memoria è out of memory.
  • Fai attenzione a seguire il modello Node.js non eseguendo attività ad alta intensità di calcolo nel thread principale, in quanto 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 unendo il 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 un valore di foo a un plug-in denominato response-override, inserisci questo codice nel file default.yaml:

response-override:
    param: foo

Dopodiché, puoi accedere al parametro nel codice del 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 di microgateway unita e ai dati di Apigee Edge scaricati nell'oggetto secondario config.emgConfigs. Ad esempio, puoi accedere a questi dati di configurazione nella funzione init nel seguente modo:

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

Di seguito è riportato un esempio di dati che emgConfigs contiene:

{
    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 object 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 di microgateway.

  • treqErrors: il numero di richieste di destinazione con errori.
  • treqErrors: il numero di risposte target con errori.
  • statusCodes: un oggetto contenente i conteggi dei codici 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.
  • connessioni: il numero di connessioni di destinazione attive.

Informazioni sulla funzione next()

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

Supponiamo che i dati vengano inviati nella richiesta 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 sugli errori, che puoi quindi gestire in una funzione successiva della catena. Se lo imposti su null, un argomento falso, significa che non ci sono errori e l'elaborazione della richiesta deve procedere normalmente. Se questo argomento è truthy (ad esempio un oggetto Error), l'elaborazione della richiesta si interrompe e la richiesta viene inviata alla destinazione.

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

Vediamo come potrebbe apparire:

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 (che si presume siano 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 di backend.

Tieni presente che puoi 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.

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

L'esempio seguente è progettato per aiutarti a comprendere questa sequenza di esecuzione.

1. Crea tre plug-in semplici

Considera il seguente plug-in. Stampa solo l'output della console quando vengono chiamati i relativi gestori di eventi:

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, crea altri due plug-in, plugin-2 e plugin-3, con lo stesso codice (tranne che devi modificare le istruzioni console.log() in plugin-2 e plugin-3 rispettivamente).

2. Esamina il codice del plug-in

Le funzioni del plug-in esportate in <microgateway-root-dir>/plugins/plugin-1/index.js sono gestori di eventi che vengono eseguiti in momenti specifici durante l'elaborazione di richieste e risposte. Ad esempio, onrequest viene eseguito quando viene ricevuto il primo byte delle intestazioni della richiesta. Mentre, onend_response viene eseguito dopo aver ricevuto l'ultimo byte dei dati di risposta.

Dai un'occhiata al gestore ondata_response: viene chiamato ogni volta che viene ricevuto un blocco di dati di risposta. La cosa importante da sapere è che i dati delle risposte non vengono necessariamente ricevuti tutti contemporaneamente. I dati potrebbero invece essere ricevuti in blocchi di lunghezza arbitraria.

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

Continuando con questo esempio, aggiungeremo i plug-in alla sequenza di plug-in nel file di configurazione di Edge Microgateway (~./edgemicro/config.yaml) come segue. La sequenza è importante. Definisce l'ordine di esecuzione dei gestori dei plug-in.

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

4. Esamina l'output di debug

Ora esaminiamo l'output che verrebbe prodotto quando vengono chiamati questi plug-in. Ci sono alcuni punti importanti da notare:

  • La sequenza di plug-in del file di configurazione di 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 appaiono nella sequenza dei plug-in: 1, 2, 3).
  • I gestori delle risposte vengono chiamati in ordine decrescente: 3, 2, 1.
  • Il gestore ondata_response viene chiamato una volta per ogni blocco di dati che arriva. In questo esempio (output mostrato di seguito), vengono ricevuti due blocchi.

Di seguito è riportato un esempio di output di debug prodotto 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 vengono chiamati i gestori dei plug-in è molto importante quando tenti di implementare funzionalità personalizzate dei plug-in, ad esempio accumulare e trasformare i dati di richiesta o risposta.

Ricorda solo che i gestori delle 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 di un altro client sovrascriverà la prima. L'unico posto sicuro per salvare lo stato del plug-in è memorizzarlo in una proprietà dell'oggetto richiesta o risposta (la cui durata è limitata a quella della richiesta).

Riscrittura degli URL di destinazione nei plug-in

Aggiunto nella versione: 2.3.3

Puoi sostituire l'URL di destinazione predefinito in un plug-in in modo dinamico modificando queste variabili nel codice del plug-in: req.targetHostname e req.targetPath.

Aggiunto in: v2.4.x

Puoi anche ignorare la porta dell'endpoint di destinazione e scegliere tra HTTP e HTTPS. Modifica queste variabili nel codice del 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.

A Edge Microgateway è stato aggiunto un plug-in di esempio chiamato eurekaclient. Questo plug-in mostra come utilizzare le variabili req.targetPort e req.targetSecure e illustra come Edge Microgateway può eseguire la ricerca dinamica degli endpoint utilizzando Eureka come catalogo degli endpoint di servizio.


Plug-in di esempio

Questi plug-in vengono forniti con l'installazione di Edge Microgateway. 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.

accumulate-request

Questo plug-in accumula i blocchi di dati del client in una proprietà array collegata all'oggetto richiesta. Quando vengono ricevuti tutti i dati della richiesta, l'array viene concatenato in un buffer che viene poi passato al plug-in successivo della sequenza. Questo plug-in deve essere il primo nella 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);

    }

  };

}

accumulate-response

Questo plug-in accumula i blocchi di dati dalla destinazione in una proprietà array collegata all'oggetto risposta. Quando vengono ricevuti tutti i dati di risposta, l'array viene concatenato in un buffer che viene poi 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 di Edge Microgateway includono un plug-in di esempio chiamato <microgateway-root-dir>/plugins/header-uppercase. L'esempio include commenti che descrivono ogni gestore di funzioni. Questo esempio esegue una semplice trasformazione 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();
    }

  };

}

transform-uppercase

Si tratta di un plug-in di trasformazione generico che puoi modificare per eseguire qualsiasi tipo di trasformazione desideri. Questo esempio trasforma semplicemente i dati di risposta e richiesta in maiuscolo.

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

  };

}