Cómo desarrollar complementos personalizados

Estás viendo la documentación de Apigee Edge.
Ve a la documentación de Apigee X.
Información

Edge Microgateway v. 3.3.x

Público

Este tema está dirigido a los desarrolladores que desean extender las funciones de Edge Microgateway mediante la escritura de complementos personalizados. Si quieres escribir un complemento nuevo, debes tener experiencia en JavaScript y Node.js.

¿Qué es un complemento personalizado de Edge Microgateway?

Un complemento es un módulo de Node.js que agrega funcionalidad a Edge Microgateway. Los módulos de complementos siguen un patrón coherente y se almacenan en una ubicación conocida por Edge Microgateway, lo que permite que se detecten y se ejecuten automáticamente. Se proporcionan varios complementos predefinidos cuando instalas Edge Microgateway. Esto incluye complementos para autenticación, protección contra aumentos de tráfico, cuotas y estadísticas. Estos complementos existentes se describen en el artículo Cómo usar complementos.

Puedes agregar funciones y capacidades nuevas a la micropuerta de enlace si escribes complementos personalizados. De forma predeterminada, Edge Microgateway es en esencia un proxy de transferencia seguro que pasa solicitudes y respuestas sin cambios desde y hacia los servicios de destino. Con los complementos personalizados, puedes interactuar de manera programática con las solicitudes y respuestas que fluyen a través de la micropuerta de enlace.

Dónde colocar el código del complemento personalizado

Aquí se incluye una carpeta para complementos personalizados como parte de la instalación de Edge Microgateway:

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

En el ejemplo anterior, [prefix] es el directorio del prefijo npm como se describe en "¿Dónde está instalado Edge Microgateway?" en Instala Edge Microgateway.

Puedes cambiar este directorio de complementos predeterminado. Consulta Dónde encontrar complementos.

Revisa los complementos predefinidos

Antes de que intentes desarrollar tu propio complemento, comprueba que ninguno de los complementos predefinidos cumpla con tus requisitos. Estos complementos se encuentran en la siguiente ubicación:

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

En el ejemplo anterior, [prefix] es el directorio del prefijo npm. Consulta también “Dónde está instalado Edge Microgateway” en la página sobre cómo instalar Edge Microgateway.

Para obtener más información, consulta también Complementos predefinidos que se proporcionan con Edge Microgateway.

Cómo escribir un complemento simple

En esta sección, analizaremos los pasos necesarios para crear un complemento simple. Este complemento anula los datos de respuesta (sin importar cuáles sean) con la string "Hello, World!" y los imprime en la terminal.

  1. Si Edge Microgateway está en ejecución, deténlo ahora:
    edgemicro stop
    
  2. cd al directorio del complemento personalizado:

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

    En el ejemplo anterior, [prefix] es el directorio del prefijo npm como se describe en “¿Dónde está instalado Edge Microgateway” en Instala Edge Microgateway?

  3. Crea un proyecto de complemento nuevo llamado response-override y ejecuta cd con él:
    mkdir response-override && cd response-override
    
  4. Crea un proyecto nuevo de Node.js:
    npm init
    
    Haz clic en Return varias veces para aceptar los valores predeterminados.
  5. Usa un editor de texto para crear un archivo nuevo llamado index.js.
  6. Copia el siguiente código en index.js y guarda el archivo.
    '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. Ya creaste un complemento y debes agregarlo a la configuración de Edge Microgateway. Abre el archivo $HOME/.edgemicro/[org]-[env]-config.yaml, en el que org y env son los nombres de la organización de Edge y del entorno.
  8. Agrega el complemento response-override al elemento plugins:sequence como se muestra a continuación.
          ...
          
          plugins:
            dir: ../plugins
            sequence:
              - oauth
              - response-override
              
          ...
    
  9. Reinicia Edge Microgateway.
  10. Llama a una API a través de Edge Microgateway. (En esta llamada a la API, se supone que estableciste la misma configuración que en el instructivo con la seguridad de la clave de API, como se describe en Configura y configura Edge Microgateway:
    curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo
    Hello, World!
    

Anatomía de un complemento

En el siguiente complemento de ejemplo de Edge Microgateway ilustra el patrón que se debe seguir cuando se desarrollan tus propios complementos. El código fuente del complemento de muestra que se analiza en esta sección se encuentra en plugins/header-uppercase/index.js.

  • Los complementos son módulos de NPM estándar con un package.json y index.js en la carpeta raíz.
  • Un complemento debe exportar una función init().
  • La función init() tiene tres argumentos: config, logger y stats. Estos argumentos se describen en los argumentos de la función init() del complemento.
  • init() muestra un objeto con controladores de funciones con nombre a los que se llama cuando ocurren ciertos eventos durante el ciclo de vida de una solicitud.

Funciones del controlador de eventos

Un complemento debe implementar algunas o todas estas funciones del controlador de eventos. Tú decides la implementación de estas funciones. Cualquier función es opcional, y un complemento típico implementará al menos un subconjunto de estas funciones.

Solicita controladores de eventos de flujo

Estas funciones se llaman en eventos de solicitud en Edge Microgateway.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

Función onrequest

Se llama al comienzo de la solicitud del cliente. Esta función se activa cuando Edge Microgateway recibe el primer byte de la solicitud. Esta función te brinda acceso a los encabezados de la solicitud, la URL, los parámetros de consulta y el método HTTP. Si llamas a continuación con un primer argumento fiable (como una instancia de error), solicitas que se detenga el procesamiento y no se inicie una solicitud de destino.

Ejemplo:

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

Función ondata_request

Se llama cuando se recibe un fragmento de datos del cliente. Pasa los datos de la solicitud al siguiente complemento en la secuencia del complemento. El valor que se muestra del último complemento en la secuencia se envía al destino. Un caso de uso típico, que se muestra a continuación, es transformar los datos de la solicitud antes de enviarlos al destino.

Ejemplo:

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

Función onend_request

Se llama cuando se reciben todos los datos de la solicitud del cliente.

Ejemplo:

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

Función onclose_request

Indica que se cerró la conexión del cliente. Puedes usar esta función en los casos en los que la conexión del cliente no sea confiable. Se llama cuando se cierra la conexión de sockets con el cliente.

Ejemplo:

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

Función onerror_request

Se llama si hay un error cuando se recibe la solicitud del cliente.

Ejemplo:

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

Controladores de eventos de flujo de respuesta

Estas funciones se llaman en eventos de respuesta en Edge Microgateway.

  • onresponse
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

Función onresponse

Se llama al comienzo de la respuesta objetivo. Esta función se activa cuando Edge Microgateway recibe el primer byte de la respuesta. Esta función te brinda acceso a los encabezados de respuesta y al código de estado.

Ejemplo:

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


Función ondata_response

Se llama cuando se recibe un fragmento de datos del objetivo.

Ejemplo:

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


Función onend_response

Se llama cuando se reciben todos los datos de respuesta del objetivo.

Ejemplo:

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

Función onclose_response

Indica que se cerró la conexión de destino. Puedes usar esta función en los casos en los que la conexión de destino no sea confiable. Se llama cuando se cierra la conexión de sockets al destino.

Ejemplo:

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


Función onerror_response

Se llama si hay un error cuando se recibe la respuesta objetivo.

Ejemplo:

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

Qué debes saber sobre las funciones del controlador de eventos del complemento

Se llama a las funciones del controlador de eventos del complemento en respuesta a eventos específicos que ocurren mientras Edge Microgateway procesa una solicitud a la API determinada.

  • Cada uno de los controladores de la función init() (ondata_request, ondata_response, etc.) debe llamar a la devolución de llamada next() cuando termine el procesamiento. Si no llamas a next(), se detendrá el procesamiento y se detendrá la solicitud.
  • El primer argumento de next() puede ser un error que provocará que finalice el procesamiento de solicitudes.
  • Los controladores ondata_ y onend_ deben llamar a next() con un segundo argumento que contenga los datos que se pasarán al destino o al cliente. Este argumento puede ser nulo si el complemento se está almacenando en búfer y no tiene suficientes datos para la transformación en ese momento.
  • Ten en cuenta que se usa una sola instancia del complemento para atender todas las solicitudes y respuestas. Si un complemento desea conservar el estado por solicitud entre llamadas, puede guardar ese estado en una propiedad agregada al objeto request suministrado (req), cuya vida útil sea la duración de la llamada a la API.
  • Procura detectar todos los errores y llamar a next() con el error. Si no se llama a next(), se detendrá la llamada a la API.
  • Ten cuidado de no generar fugas de memoria, ya que pueden afectar el rendimiento general de Edge Microgateway y hacer que falle si se queda sin memoria.
  • Ten cuidado de seguir el modelo de Node.js y no realices tareas de procesamiento intensivo en el subproceso principal, ya que esto puede afectar negativamente el rendimiento de Edge Microgateway.

Información acerca de la función init() del complemento

En esta sección, se describen los argumentos que se pasan a la función init(): config, logger y stats.

config

Los datos de configuración que se obtienen con la combinación del archivo de configuración de Edge Microgateway con los datos descargados desde Apigee Edge se colocan en un objeto denominado: config.

Para agregar un parámetro de configuración llamado param con un valor de foo a un complemento llamado response-override, coloca esto en el archivo default.yaml:

response-override:
    param: foo

Luego, puedes acceder al parámetro en el código de tu complemento de la siguiente manera:

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

En este caso, verás foo impreso en el resultado de depuración del complemento:

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

Puedes acceder a la configuración combinada de microgateway y descargar los datos de Apigee Edge en el objeto secundario config.emgConfigs. Por ejemplo, puedes acceder a estos datos de configuración en la función init de la siguiente manera:

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

A continuación, se muestra un ejemplo de datos que contiene 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

El registrador del sistema. El registrador empleado actualmente exporta estas funciones, en las que el objeto puede ser una string, una solicitud HTTP, una respuesta HTTP o una instancia de error.

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

stats

Un objeto que contiene recuentos de solicitudes, respuestas, errores y otras estadísticas agregadas relacionadas con las solicitudes y respuestas que fluyen a través de una instancia de micropuerta de enlace.

  • treqErrors: la cantidad de solicitudes de destino con errores.
  • treqErrors: la cantidad de respuestas objetivo con errores.
  • statusCodes: un objeto que contiene recuentos de códigos de respuesta:
{
  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
  }
  
  • solicitudes: La cantidad total de solicitudes.
  • respuestas: la cantidad total de respuestas.
  • connections: La cantidad de conexiones de destino activas.

Acerca de la función next()

Todos los métodos del complemento deben llamar a next() para continuar procesando el siguiente método de la serie (de lo contrario, el proceso del complemento se bloqueará). En el ciclo de vida de la solicitud, el primer método al que se llama es onrequest(). El siguiente método que se debe llamar es el método ondata_request(). Sin embargo, solo se llama a ondata_request si la solicitud incluye datos, como en el caso, por ejemplo, de una solicitud POST. El siguiente método al que se llamará será onend_request(), que se llama cuando se completa el procesamiento de la solicitud. Solo se llama a las funciones onerror_* en caso de que se produzca un error. Si lo deseas, puedes controlar los errores con código personalizado.

Supongamos que se envían datos en la solicitud y se llama a ondata_request(). Ten en cuenta que la función llama a next() con dos parámetros:

next(null, data);

Por convención, el primer parámetro se usa para transmitir información de errores, que luego puedes manejar en una función posterior de la cadena. Si lo configuras como null, un argumento falso, significa que no hay errores, y que el procesamiento de la solicitud debería continuar con normalidad. Si este argumento es veraz (como un objeto Error), la solicitud se detendrá en el procesamiento y la solicitud se enviará al destino.

El segundo parámetro pasa los datos de la solicitud a la siguiente función de la cadena. Si no realizas ningún procesamiento adicional, los datos de la solicitud se pasan sin cambios al destino de la API. Sin embargo, puedes modificar los datos de la solicitud en este método y pasar la solicitud modificada al destino. Por ejemplo, si los datos de la solicitud son XML y el destino espera JSON, puedes agregar código al método ondata_request() que (a) cambie el tipo de contenido del encabezado de la solicitud a application/json y convierta los datos de la solicitud a JSON con el medio que desees (por ejemplo, puedes usar un convertidor xml2json de Node.js obtenido de NPM).

Veamos cómo podría ser:

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

En este caso, los datos de la solicitud (que se supone que son XML) se convierten a JSON y los datos transformados se pasan a través de next() a la siguiente función en la cadena de solicitudes antes de pasarse al destino del backend.

Ten en cuenta que puedes agregar otra declaración de depuración para imprimir los datos transformados con fines de depuración. Por ejemplo:

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

Acerca del orden de ejecución del controlador del complemento

Si escribes complementos para Edge Microgateway, debes comprender el orden en el que se ejecutan los controladores de eventos del complemento.

El punto importante que debes recordar es que cuando especificas una secuencia de complementos en el archivo de configuración de Edge Microgateway, los controladores de solicitudes se ejecutan en orden ascendente, mientras que los controladores de respuesta se ejecutan en orden descendente.

El siguiente ejemplo está diseñado para ayudarte a comprender esta secuencia de ejecución.

1. Crea tres complementos simples

Considera el siguiente complemento. Todo lo que hace es el resultado de la consola de impresión cuando se llama a sus controladores de eventos:

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

Ahora, considera crear dos complementos más, plugin-2 y plugin-3, con el mismo código (excepto que debes cambiar las declaraciones console.log() a plugin-2 y plugin-3 respectivamente).

2. Cómo revisar el código del complemento

Las funciones de complementos exportadas en <microgateway-root-dir>/plugins/plugin-1/index.js son controladores de eventos que se ejecutan en momentos específicos durante el procesamiento de solicitudes y respuestas. Por ejemplo, onrequest ejecuta el primer byte de los encabezados de solicitud que se recibe. Mientras que onend_response se ejecuta después de recibir el último byte de datos de respuesta.

Observa el controlador ondata_response; se llama cada vez que se recibe un fragmento de datos de respuesta. Lo importante que debes saber es que los datos de respuesta no necesariamente se reciben todos a la vez. En cambio, los datos se pueden recibir en fragmentos de longitud arbitraria.

3. Cómo agregar complementos a la secuencia de complementos

Para continuar con este ejemplo, agregaremos los complementos a la secuencia de complementos en el archivo de configuración de Edge Microgateway (~./edgemicro/config.yaml) de la siguiente manera. La secuencia es importante. Define el orden en el que se ejecutan los controladores del complemento.

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

4. Examina el resultado de depuración

Ahora, veamos el resultado que se produce cuando se llama a estos complementos. Debes tener en cuenta algunos puntos importantes:

  • La secuencia del complemento del archivo de configuración de Edge Microgateway (~./edgemicro/config.yaml) especifica el orden en el que se llama a los controladores de eventos.
  • Los controladores de solicitudes se llaman en orden ascendente (el orden en el que aparecen en la secuencia del complemento: 1, 2, 3).
  • Los controladores de respuestas se llaman en orden descendente: 3, 2, 1.
  • Se llama al controlador ondata_response una vez por cada fragmento de datos que llega. En este ejemplo (el resultado se muestra a continuación), se reciben dos fragmentos.

A continuación, se muestra un resultado de depuración de muestra que se produce cuando estos tres complementos están en uso y se envía una solicitud a través de Edge Microgateway. Solo observa el orden en el que se llama a los controladores:

  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

Resumen

Comprender el orden en el que se llama a los controladores de complementos es muy importante cuando intentas implementar una funcionalidad de complementos personalizados, como la acumulación y transformación de datos de solicitud o respuesta.

Solo recuerda que los controladores de solicitudes se ejecutan en el orden en que se especifican los complementos en el archivo de configuración de Edge Microgateway y los controladores de respuesta se ejecutan en el orden opuesto.

Información acerca del uso de variables globales en complementos

Cada solicitud a Edge Microgateway se envía a la misma instancia de un complemento. Por lo tanto, el estado de una segunda solicitud de otro cliente reemplazará la primera. El único lugar seguro para guardar el estado del complemento es almacenarlo en una propiedad del objeto de solicitud o respuesta (cuyo ciclo de vida se limita al de la solicitud).

Reescribe URLs de destino en complementos

Se agregó en la versión 2.3.3

Para anular la URL de destino predeterminada de un complemento de forma dinámica, modifica estas variables en el código del complemento: req.targetHostname y req.targetPath.

Se agregó en la versión 2.4.x

También puedes anular el puerto del extremo de destino y elegir entre HTTP y HTTPS. Modifica estas variables en el código de tu complemento: req.targetPort y req.targetSecure. Para elegir HTTPS, configura req.targetSecure en true; para HTTP, configúralo como false. Si configuras req.targetSecure como verdadero, consulta esta conversación para obtener más información.

Se quitó en la versión 3.3.3

El complemento de muestra llamado eurekaclient se quitó de Edge Microgateway en la versión 3.3.3. Consulta Notas de la versión.

La eliminación de esta función no afecta la funcionalidad principal de la micropuerta de enlace de Edge ni la reescritura de las URLs de destino. Puedes configurar la búsqueda dinámica de extremos y anular las variables de destino como req.targetHostname, req.targetPath, req.targetPort y req.targetSecure a nivel del complemento. Consulta Reescribe URLs de destino en complementos.


Complementos de muestra

Estos complementos se proporcionan con la instalación de Edge Microgateway. Puedes encontrarlas en la instalación de Edge Microgateway aquí:

[prefix]/lib/node_modules/edgemicro/plugins

En el ejemplo anterior, [prefix] es el directorio del prefijo npm como se describe en "¿Dónde está instalado Edge Microgateway?" en Instala Edge Microgateway.

solicitud-de-acumulación

Este complemento acumula fragmentos de datos del cliente en una propiedad de array adjunta al objeto de solicitud. Cuando se reciben todos los datos de la solicitud, el arreglo se concatena en un búfer que, luego, se pasa al siguiente complemento de la secuencia. Este complemento debería ser el primero de la secuencia para que los complementos posteriores reciban los datos de solicitudes acumulados.

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

    }

  };

}

acumular-respuesta

Este complemento acumula fragmentos de datos del objetivo en una propiedad de array adjunta al objeto de respuesta. Cuando se reciben todos los datos de respuesta, el arreglo se concatena en un búfer que, luego, se pasa al siguiente complemento de la secuencia. Debido a que este complemento opera en respuestas, que se procesan en orden inverso, debes colocarlo como el último complemento de la secuencia.

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

  };

}

Complemento encabezado en mayúsculas

Las distribuciones de Edge Microgateway incluyen un complemento de muestra llamado <microgateway-root-dir>/plugins/header-uppercase. La muestra incluye comentarios que describen cada uno de los controladores de funciones. En esta muestra, se realiza una transformación de datos simple de la respuesta objetivo y se agregan encabezados personalizados a la solicitud del cliente y la respuesta objetivo.

Este es el código fuente 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();
    }

  };

}


transformación-mayúsculas

Este es un complemento de transformación general que puedes modificar para realizar el tipo de transformación que desees. En este ejemplo, solo se transforman los datos de respuesta y solicitud a mayúsculas.

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

  };

}