Estás viendo la documentación de Apigee Edge.
Ve a la
Documentación de Apigee X. información
Público
Este tema está dirigido a desarrolladores que desean extender las funciones de Edge Microgateway escribiendo complementos personalizados. Si deseas escribir un nuevo complemento, es importante que tengas experiencia con JavaScript y Node.js como en los productos necesarios.
¿Qué es un complemento personalizado de Edge Microgateway?
Un complemento es un módulo de Node.js que agrega funcionalidad a Edge Microgateway. 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 descubran y ejecuten automáticamente. Se proporcionan varios complementos predefinidos cuando instalar Edge Microgateway. Estos incluyen complementos para la autenticación, la protección contra aumentos de tráfico, la cuota y de análisis de datos en la nube. Estos complementos existentes se describen en Cómo usar complementos.
Puedes agregar nuevas funciones y capacidades a microgateway escribiendo personalizado complementos. De forma predeterminada, Edge Microgateway es básicamente un proxy de transferencia seguro que pase las solicitudes y respuestas sin cambios hacia y desde los servicios objetivo. Con los complementos personalizados, puedes interactuar de manera programática con las solicitudes y respuestas que fluyen a través de microgateway.
Dónde colocar el código personalizado del complemento
Se incluye una carpeta para complementos personalizados como parte de la instalación de Edge Microgateway. aquí:
[prefix]/lib/node_modules/edgemicro/plugins
donde [prefix] es el directorio del prefijo npm, como
descrito en la sección “¿Dónde está instalado Edge Microgateway?” en Cómo instalar 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, verifica que ninguno de los complementos complementos cumplan con tus requisitos. Estos complementos se encuentran en las siguientes ubicaciones:
[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 Cómo instalar Edge
Microgateway
Para obtener más información, consulta también la sección Predefinidos complementos 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 (sean cuales sean) con la cadena "Hello, World!" y lo imprime en la terminal.
- Si se está ejecutando Edge Microgateway, detenla ahora:
edgemicro stop
-
cdal directorio del complemento personalizado:cd [prefix]/lib/node_modules/edgemicro/pluginsEn el ejemplo anterior,
[prefix]es el directorio del prefijonpm. como se describe en “Dónde está instalado Edge Microgateway” en Cómo instalar Edge Microgateway - Crea un nuevo proyecto de complemento
llamada response-override y
cd:
mkdir response-override && cd response-override
- Crea un proyecto de Node.js nuevo:
Haz clic en Intro varias veces para aceptar los valores predeterminados.npm init
- Usa un editor de texto para crear un archivo nuevo llamado
index.js. - Copia el siguiente código en
index.jsy 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"); } }; }
- Ahora que creaste un complemento y debes agregarlo a la configuración de Edge Microgateway.
Abre el archivo
$HOME/.edgemicro/[org]-[env]-config.yaml. en el queorgyenvson tu organización de Edge y los nombres de los entornos. - Agrega el complemento
response-overrideal el elementoplugins:sequence, como se muestra a continuación.
... plugins: dir: ../plugins sequence: - oauth - response-override ... - Reinicia Edge Microgateway.
- Llamar a una API a través de Edge Microgateway (Esta llamada a la API supone que configuraste el mismo
como el instructivo con la seguridad de la clave de API, como se describe en Configuración
configurar y configurar 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 muestra de Edge Microgateway, se ilustra el patrón que se debe seguir cuando
desarrollar tus propios complementos. El código fuente del complemento de muestra que se analiza en esta sección es
por la plugins/header-uppercase/index.js.
- Los complementos son módulos NPM estándar con
un
package.jsony unindex.jsen la raíz carpeta. - Los complementos deben exportar una función init().
- La función init() toma tres argumentos: config, logger y stats. Estos argumentos se describen en Argumentos de la función init() del complemento.
- init() muestra un objeto con controladores de funciones con nombre que se llaman 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. Implementación de estas funciones depende de ti. Cualquier función es opcional, y se implementará un complemento típico al al menos un subconjunto de estas funciones.
Cómo solicitar controladores de eventos de flujo
Estas funciones se llaman en eventos de solicitud en Edge Microgateway.
onrequestondata_requestonend_requestonclose_requestonerror_request
Función onrequest
Se llama al comienzo de la solicitud del cliente. Esta función se activa cuando el primer byte de la que Edge Microgateway recibe la solicitud. Esta función te da acceso a los encabezados de la solicitud, URL, parámetros de consulta y método HTTP. Si llamas a continuación con un primer argumento honesto (como un de error), se detiene el procesamiento de la solicitud y no se inicia la 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. Se pasan los datos de la solicitud al siguiente en la secuencia correspondiente. El valor que se muestra del último complemento en la secuencia se envía a el objetivo. Un caso de uso típico, que se muestra a continuación, es transformar los datos de la solicitud antes de enviarlos para el objetivo.
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 que el la conexión con el cliente no es confiable. Se llama cuando se establece la conexión de socket con el cliente cerrado.
Ejemplo:
onclose_request: function(req, res, next) { debug('plugin onclose_request'); next(); }
Función onerror_request
Se llama si se produce 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 los eventos de respuesta de Edge Microgateway.
onresponseondata_responseonend_responseonclose_responseonerror_response
Función onresponse
Se llama al comienzo de la respuesta objetivo. Esta función se activa cuando el primer byte de la que Edge Microgateway recibe la respuesta. Esta función te da acceso a los encabezados de respuesta y 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 destino.
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 destino.
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 que el la conexión de destino no es confiable. Se llama a este método cuando la conexión del socket con el destino se cerrado.
Ejemplo:
onclose_response: function(req, res, next) { debug('plugin onclose_response'); next(); }
Función onerror_response
Se llama si se produce un error cuando se recibe la respuesta deseada.
Ejemplo:
onerror_response: function(req, res, err, next) { debug('plugin onerror_response ' + err); next(); }
Lo que debes saber sobre la funciones del controlador de eventos del complemento
Las funciones del controlador de eventos de complementos se llaman 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.) deben llamar. la devolución de llamada next() cuando haya terminado el procesamiento Si no llamar a next(), se detendrá el procesamiento y la solicitud quedará en espera.
- El primer argumento de next() puede ser un error que causará que el procesamiento de solicitudes finalice.
- Los controladores ondata_ y onend_ deben llamar a next() con un segundo argumento que contenga los datos que se pasarán con el objetivo o el cliente. Este argumento puede ser nulo si el complemento está almacenando en búfer y no ha suficientes datos para transformarlos en este momento.
- Ten en cuenta que se utiliza una sola instancia del complemento para atender todas las solicitudes y respuestas. Si un complemento desea retener el estado por solicitud entre llamadas, puede guardarlo en Se agregó la propiedad al objeto request proporcionado. (req), cuya vida útil es la duración de la llamada a la API.
- Ten cuidado de detectar todos los errores y de llamar a next() con el error. Si no se llama a next(), se bloqueará 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.
- Procura seguir el modelo de Node.js; para ello, no realices tareas de procesamiento intensivo en la 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 la función init(): config, logger y stats.
config
Un objeto de configuración obtenido después de combinar el archivo de configuración de Edge Microgateway con
información que se descarga de Apigee Edge, como los productos y las cuotas. Puedes encontrar
configuración específica del complemento en este objeto: config.<plugin-name>.
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: fooLuego, puedes acceder al parámetro en el código del 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
logger
El registrador del sistema. El registrador empleado actualmente exporta estas funciones, donde los objetos pueden una cadena, una solicitud HTTP, una respuesta HTTP o una instancia de error.
info(object, message)warn(object, message)error(object, message)
estadísticas
Un objeto que contiene recuentos de solicitudes, respuestas, errores y otras estadísticas agregadas relacionados con las solicitudes y respuestas que fluyen a través de una instancia de microgateway.
- treqErrors: la cantidad de solicitudes de destino con errores.
- treqErrors: el número 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 la siguiente
método de la serie (de lo contrario, se bloqueará el proceso del complemento). En el ciclo de vida de la solicitud, la primera
método llamado es onrequest(). El siguiente método al que se debe llamar es
el método ondata_request()
Sin embargo, se llama a ondata_request solo si el elemento
incluye datos, como en el caso de una solicitud POST. El siguiente método llamado
será onend_request(), al que se llama cuando se procesa la solicitud
el proyecto se completó. Solo se llama a las funciones onerror_* si se produce una
y te permiten manejar los errores con un código personalizado, si lo deseas.
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 error, que luego puedes
en una función posterior de la cadena. Si lo estableces en null, se generará un
significa que no hay errores y que el procesamiento de la solicitud debería continuar normalmente. Si
este argumento es verdadero (como un objeto Error), el procesamiento de la solicitud se detiene y la solicitud
que se envían al objetivo.
El segundo parámetro pasa los datos de la solicitud a la siguiente función en la cadena. Si no realizas ninguna acción
procesamiento adicional, los datos de la solicitud se pasan sin cambios al destino de la API.
Sin embargo, tienes la oportunidad de modificar los datos de la solicitud en este método y pasar el
solicitud al objetivo. Por ejemplo, si los datos de la solicitud son XML y el destino espera JSON,
Luego, puedes agregar código al método ondata_request() que (a) cambie la
Content-Type del encabezado de la solicitud a application/json y convierte el
solicitar datos a JSON con el medio que desees (por ejemplo, podrías usar una
Conversor xml2json de Node.js obtenido de NPM.
Veamos cómo podría verse:
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 el
Los datos transformados se pasan a través de next() a la siguiente función de la solicitud.
antes de pasarlos al destino del backend.
Ten en cuenta que puedes agregar otra sentencia de depuración a fin de imprimir los datos transformados para la depuración. comerciales. 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); },
Información orden de ejecución del controlador de complementos
Si escribes complementos para Edge Microgateway, debes saber el orden en el que se ejecuten controladores de eventos.
Lo importante que debes recordar es que cuando especificas una secuencia de complementos en el extremo El archivo de configuración de Microgateway, los controladores de solicitudes se ejecutan en orden ascendente, mientras que los controladores de respuestas se ejecutan en orden descendente.
El siguiente ejemplo está diseñado para ayudarte a comprender esta secuencia de ejecución.
1. Crea tres consultas simples complementos
Considera el siguiente complemento. Todo lo que hace es imprimir el resultado de la consola cuando sus controladores de eventos llamado:
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 más
complementos, plugin-2 y plugin-3, con el mismo código
(excepto, cambiar las sentencias console.log())
a plugin-2 y plugin-3 respectivamente).
2. Cómo revisar el código del complemento
Las funciones del complemento exportadas
en <microgateway-root-dir>/plugins/plugin-1/index.js son eventos
que se ejecutan en momentos específicos durante el procesamiento de solicitudes y respuestas. Para
Por ejemplo, onrequest ejecuta el primer byte de los encabezados de la solicitud.
recibidos. Mientras que onend_response se ejecuta después del último byte de respuesta
cuando se reciben los datos.
Observa el controlador ondata_response: se llama cada vez que se llama a un fragmento de datos de respuesta. de configuración. Lo importante es saber que los datos de respuesta no necesariamente se reciben al una vez. En cambio, los datos se pueden recibir en fragmentos de longitud arbitraria.
3. Agrega los complementos al la secuencia del complemento
Para continuar con este ejemplo, agregaremos los complementos a la secuencia de complementos en Edge
El archivo de configuración de Microgateway (~./edgemicro/config.yaml) como se indica a continuación. La secuencia es
importante. Define el orden en 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 produciría cuando se llame a estos complementos. Existen algunos puntos importantes a tener en cuenta:
- El complemento secuencia el archivo de configuración de Edge Microgateway
(
~./edgemicro/config.yaml) especifica el orden en el que se ejecutan los controladores de eventos llamado. - Los controladores de solicitudes se llaman en orden ascendente (el orden en 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_responseuna vez por cada fragmento de datos. que llega. En este ejemplo (resultado que se muestra a continuación), se reciben dos fragmentos.
Este es un ejemplo de resultado de depuración producido 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 llaman 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
Es muy importante comprender el orden en el que se llaman a los controladores de complementos cuando intentas implementar funcionalidades de complementos personalizados, como acumular y transformar solicitudes o respuestas de datos no estructurados.
Recuerda que los controladores de solicitudes se ejecutan en el orden en que los complementos especificadas en el archivo de configuración de Edge Microgateway y los controladores de respuestas 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, un el estado de la segunda solicitud de otro cliente reemplazará el primero. El único lugar seguro para el estado del complemento es almacenar el estado en una propiedad en el objeto de solicitud o respuesta (cuyos la vida útil se limita a la de la solicitud).
Reescribe las URLs de destino en complementos
Agregado en la versión 2.3.3
Complementos de muestra
Estos complementos se proporcionan con la instalación de Edge Microgateway. Puedes encontrarlas en la Instala Edge Microgateway aquí:
[prefix]/lib/node_modules/edgemicro/plugins
donde [prefix] es el directorio del prefijo npm, como
descrito en la sección “¿Dónde está instalado Edge Microgateway?” en Cómo instalar Edge
Microgateway
accumulate-request
Este complemento acumula fragmentos de datos del cliente en una propiedad de array conectada al request. Cuando se reciben todos los datos de la solicitud, el array se concatena en un búfer. que luego se pasa al siguiente complemento de la secuencia. Este complemento debería ser el primero en la secuencia para que los complementos posteriores reciban los datos de solicitud 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); } };
accumulate-response
Este complemento acumula fragmentos de datos del destino en una propiedad de array adjunta al objeto de respuesta. Cuando se reciben todos los datos de respuesta, el array se concatena en un búfer que luego se pasa al siguiente complemento de la secuencia. Como este complemento opera en que se procesan en orden inverso, debes colocarlas como el último complemento en 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 = null; if(res._chunks && res._chunks.length) { content = Buffer.concat(res._chunks); } delete res._chunks; next(null, content); } }; }
complementoheader-uppercase
Las distribuciones de Edge Microgateway incluyen un complemento de muestra
llamada <microgateway-root-dir>/plugins/header-uppercase. La muestra
incluye comentarios que describen cada uno de los controladores de la función. En esta muestra, se usan algunos datos simples
transformación de la respuesta de destino y agrega encabezados personalizados a la solicitud del cliente y al destino
respuesta.
Este es el código fuente
para <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(); } }; }
transformar-mayúscula
Este es un complemento de transformación general que puedes modificar para realizar y la transformación que quieras. En este ejemplo, simplemente 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); } }; }
Instructivos adicionales de complementos
Consulta también estos instructivos en el blog de Apigee: