Desenvolver plug-ins personalizados

Você está vendo a documentação do Apigee Edge.
Acesse a documentação da Apigee X.
informações

Edge Microgateway v. 3.3.x

Público-alvo

Este tópico é destinado a desenvolvedores que querem ampliar os recursos do Edge Microgateway criando plug-ins personalizados. Se quiser escrever um novo plug-in, é necessário ter experiência com JavaScript e Node.js.

O que é um plug-in personalizado do Edge Microgateway?

Um plug-in é um módulo do Node.js que adiciona funcionalidades ao Edge Microgateway. Os módulos de plug-in seguem um padrão consistente e são armazenados em um local conhecido pelo Edge Microgateway, o que permite que eles sejam descobertos e executados automaticamente. Vários plug-ins predefinidos são fornecidos quando você instala o Edge Microgateway. Isso inclui plug-ins para autenticação, detenção de pico, cota e análise. Esses plug-ins são descritos em Usar plug-ins.

É possível adicionar novos recursos ao microgateway escrevendo plug-ins personalizados. Por padrão, o Edge Microgateway é essencialmente um proxy de passagem seguro que transmite solicitações e respostas inalteradas para e de serviços de destino. Com plug-ins personalizados, é possível interagir programaticamente com as solicitações e respostas que fluem pelo microgateway.

Onde colocar o código do plug-in personalizado

Uma pasta para plug-ins personalizados está incluída como parte da instalação do Edge Microgateway aqui:

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

em que [prefix] é o diretório de prefixo npm, conforme descrito em "Onde o Edge Microgateway está instalado" em Como instalar o Edge Microgateway.

É possível alterar esse diretório de plug-in padrão. Consulte Onde encontrar plug-ins.

Analisar os plug-ins predefinidos

Antes de tentar desenvolver seu próprio plug-in, é importante verificar se nenhum dos plug-ins predefinidos atende aos seus requisitos. Esses plug-ins estão localizados em:

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

em que [prefix] é o diretório de prefixos npm. Consulte também "Onde o Edge Microgateway está instalado" em Como instalar o Edge Microgateway.

Para mais detalhes, consulte também Plug-ins predefinidos fornecidos com o Edge Microgateway.

Criar um plug-in simples

Nesta seção, vamos analisar as etapas necessárias para criar um plug-in simples. Esse plug-in substitui os dados de resposta (qualquer um) pela string "Hello, World!" e os imprime no terminal.

  1. Se o Edge Microgateway estiver em execução, interrompa-o agora:
    edgemicro stop
    
  2. cd ao diretório do plug-in personalizado:

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

    em que [prefix] é o diretório de prefixos npm, conforme descrito em "Onde o Edge Microgateway está instalado" em Como instalar o Edge Microgateway.

  3. Crie um novo projeto de plug-in chamado response-override e cd para ele:
    mkdir response-override && cd response-override
    
  4. Crie um projeto em Node.js:
    npm init
    
    Clique em "Return" várias vezes para aceitar os padrões.
  5. Use um editor de texto para criar um novo arquivo com o nome index.js.
  6. Copie o código abaixo no index.js e salve o arquivo.
    '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. Você criou um plug-in e precisa adicioná-lo à configuração do Edge Microgateway. Abra o arquivo $HOME/.edgemicro/[org]-[env]-config.yaml, em que org e env são os nomes do ambiente e da organização do Edge.
  8. Adicione o plug-in response-override ao elemento plugins:sequence, conforme mostrado abaixo.
          ...
          
          plugins:
            dir: ../plugins
            sequence:
              - oauth
              - response-override
              
          ...
    
  9. Reinicie o Edge Microgateway.
  10. Chamar uma API pelo Edge Microgateway. Para essa chamada de API, presumimos que você tenha definido a mesma configuração do tutorial com a segurança da chave de API, conforme descrito em Como instalar e configurar o Edge Microgateway:
    curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo
    Hello, World!
    

Anatomia de um plug-in

O plug-in de amostra Edge Microgateway a seguir ilustra o padrão a seguir ao desenvolver seus próprios plug-ins. O código-fonte do plug-in de amostra discutido nesta seção está no arquivo plugins/header-uppercase/index.js.

  • Os plug-ins são módulos padrão do NPM com um package.json e um index.js na pasta raiz.
  • Um plug-in precisa exportar uma função init().
  • A função init() usa três argumentos: config, logger e stats. Esses argumentos são descritos nos argumentos da função init() do plug-in.
  • init() retorna um objeto com gerenciadores de funções nomeados que são chamados quando determinados eventos ocorrem durante o ciclo de vida de uma solicitação.

Funções do manipulador de eventos

Um plug-in precisa implementar algumas ou todas essas funções de manipulador de eventos. A implementação dessas funções fica a seu critério. Qualquer função é opcional, e um plug-in típico implementará pelo menos um subconjunto dessas funções.

Manipuladores de eventos do fluxo de solicitação

Essas funções são chamadas quando ocorrem eventos de solicitação no Edge Microgateway.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

Função onrequest

Chamado no início da solicitação do cliente. Essa função é acionada quando o primeiro byte da solicitação é recebido pelo Edge Microgateway. Com essa função, você tem acesso aos cabeçalhos da solicitação, ao URL, aos parâmetros de consulta e ao método HTTP. Se você chamar "next" com um primeiro argumento verdadeiro (como uma instância de Erro), o processamento da solicitação será interrompido e uma solicitação de destino não será iniciada.

Exemplo:

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

Função ondata_request

Chamado quando um bloco de dados é recebido do cliente. Transmite dados de solicitação para o próximo plug-in na sequência. O valor retornado do último plug-in na sequência é enviado ao destino. Um caso de uso típico, mostrado abaixo, é transformar os dados da solicitação antes de enviá-los ao destino.

Exemplo:

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

Função onend_request

Chamado quando todos os dados da solicitação são recebidos do cliente.

Exemplo:

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

onclose_request função

Indica que a conexão do cliente foi encerrada. Use essa função nos casos em que a conexão do cliente não é confiável. Ele é chamado quando a conexão do soquete com o cliente é fechada.

Exemplo:

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

onerror_request função

Chamado se houver um erro ao receber a solicitação do cliente.

Exemplo:

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

Manipuladores de eventos de fluxo de resposta

Essas funções são chamadas em eventos de resposta no Edge Microgateway.

  • onresponse
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

onresponse função

Chamado no início da resposta alvo. Essa função é acionada quando o primeiro byte da resposta é recebido pelo Edge Microgateway. Com essa função, você tem acesso aos cabeçalhos de resposta e ao código de status.

Exemplo:

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


Função ondata_response

Chamado quando um bloco de dados é recebido do destino.

Exemplo:

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


Função onend_response

Chamado quando todos os dados de resposta são recebidos do alvo.

Exemplo:

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

onclose_response função

Indica que a conexão de destino foi encerrada. Use essa função nos casos em que a conexão de destino não é confiável. Ele é chamado quando a conexão do soquete com o destino é fechada.

Exemplo:

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


Função onerror_response

Chamado se houver um erro ao receber a resposta de destino.

Exemplo:

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

O que você precisa saber sobre as funções do manipulador de eventos do plug-in

As funções do manipulador de eventos do plug-in são chamadas em resposta a eventos específicos que ocorrem enquanto o Edge Microgateway processa uma determinada solicitação de API.

  • Cada um dos gerenciadores de função init() (ondata_request, ondata_response etc.) precisa chamar o callback next() quando o processamento é concluído. Se você não chamar next(), o processamento será interrompido e a solicitação travará.
  • O primeiro argumento para next() pode ser um erro que fará com que o processamento da solicitação seja encerrado.
  • Os gerenciadores ondata_ e onend_ precisam chamar next() com um segundo argumento contendo os dados a serem transmitidos para o destino ou cliente. Esse argumento poderá ser nulo se o plug-in estiver sendo armazenado em buffer e não tiver dados suficientes para transformação no momento.
  • Uma única instância do plug-in é usada para atender a todas as solicitações e respostas. Se um plug-in quiser manter o estado por solicitação entre chamadas, ele poderá salvá-lo em uma propriedade adicionada ao objeto request (req) fornecido, que tem a duração da chamada de API.
  • Tenha cuidado para capturar todos os erros e chamar next() com o erro. Se next() não forem chamados, a chamada de API travará.
  • Tenha cuidado para não introduzir vazamentos de memória, porque isso pode afetar o desempenho geral do Edge Microgateway e causar falhas se ele ficar sem memória.
  • Tenha cuidado para seguir o modelo Node.js sem realizar tarefas com uso intensivo de computação na linha de execução principal, já que isso pode afetar negativamente o desempenho do Edge Microgateway.

Sobre a função init() do plug-in

Esta seção descreve os argumentos passados para a função init(): config, logger e stats.

config

Os dados de configuração extraídos da mesclagem do arquivo de configuração do Edge Microgateway com os dados transferidos por download do Apigee Edge são colocados em um objeto chamado: config.

Para adicionar um parâmetro de configuração chamado param com um valor de foo a um plug-in chamado response-override, coloque-o no arquivo default.yaml:

response-override:
    param: foo

Em seguida, você pode acessar o parâmetro no código do plug-in da seguinte forma:

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

Nesse caso, você verá "foo" impresso na saída de depuração do plug-in:

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

É possível acessar a configuração de microgateway mesclada e os dados do Apigee Edge salvos no objeto filho config.emgConfigs. Por exemplo, é possível acessar esses dados de configuração na função init da seguinte maneira:

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

Confira abaixo um exemplo de dados que emgConfigs contém:

{
    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

O registrador do sistema. O logger empregado atualmente exporta essas funções, em que o objeto pode ser uma string, uma solicitação HTTP, uma resposta HTTP ou uma instância de erro.

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

stats

Um objeto que contém contagens de solicitações, respostas, erros e outras estatísticas agregadas relacionadas às solicitações e às respostas que fluem por uma instância de microgateway.

  • treqErrors: o número de solicitações de destino com erros.
  • treqErrors: o número de respostas de destino com erros.
  • statusCodes - um objeto contendo contagens de códigos de resposta:
{
  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
  }
  
  • solicitações: o número total de solicitações.
  • responses: o número total de respostas.
  • connections: número de conexões de destino ativas.

Sobre a função next()

Todos os métodos do plug-in precisam chamar next() para continuar processando o próximo método da série. Caso contrário, o processo do plug-in travará. No ciclo de vida da solicitação, o primeiro método chamado é onrequest(). O próximo método a ser chamado é o ondata_request(). No entanto, ondata_request é chamado somente se a solicitação incluir dados, como no caso, por exemplo, de uma solicitação POST. O próximo método chamado será onend_request(), que será chamado quando o processamento da solicitação for concluído. As funções onerror_* são chamadas apenas em caso de erro e permitem que você lide com os erros com código personalizado, se quiser.

Digamos que os dados sejam enviados na solicitação e o método ondata_request() seja chamado. A função chama next() com dois parâmetros:

next(null, data);

Por convenção, o primeiro parâmetro é usado para transmitir informações de erro, que podem ser processadas em uma função subsequente na cadeia. Ao defini-lo como null, um argumento falsy, indicamos que não há erros e que o processamento da solicitação deve prosseguir normalmente. Se esse argumento for true (como um objeto Error), o processamento da solicitação será interrompido, e a solicitação será enviada para o destino.

O segundo parâmetro transmite os dados da solicitação para a próxima função na cadeia. Se você não fizer nenhum processamento adicional, os dados da solicitação não serão alterados para o destino da API. No entanto, você tem a chance de modificar os dados da solicitação nesse método e transmitir a solicitação modificada para o destino. Por exemplo, se os dados da solicitação forem XML e o destino esperar JSON, será possível adicionar um código ao método ondata_request() que (a) muda o Content-Type do cabeçalho da solicitação para application/json e converte os dados da solicitação para JSON usando o que quiser (por exemplo, é possível usar um conversor xml2json do Node.js recebido do NPM).

Vamos conferir o resultado:

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

Nesse caso, os dados da solicitação (que deve ser XML) são convertidos em JSON e os dados transformados são transmitidos por meio de next() para a próxima função na cadeia de solicitação, antes de serem passados para o destino do back-end.

É possível adicionar outra instrução de depuração para imprimir os dados transformados para fins de depuração. Exemplo:

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

Sobre a ordem de execução do gerenciador de plug-ins

Se você criar plug-ins para o Edge Microgateway, precisará entender a ordem em que os manipuladores de eventos de plug-in são executados.

É importante lembrar que, quando você especifica uma sequência de plug-ins no arquivo de configuração do Edge Microgateway, os gerenciadores de solicitações são executados em ordem crescente, enquanto os gerenciadores de resposta são executados em ordem decrescente.

O exemplo a seguir foi criado para ajudar você a entender essa sequência de execução.

1. Criar três plug-ins simples

Considere o plug-in a seguir. Ele só faz a saída do console de impressão quando os manipuladores de eventos são chamados:

plugins/plugin-1/index.js (em inglês)

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

Agora, considere criar mais dois plug-ins, plugin-2 e plugin-3, com o mesmo código (exceto, alterar as instruções console.log() para plugin-2 e plugin-3, respectivamente).

2. Revisar o código do plug-in

As funções de plug-in exportadas em <microgateway-root-dir>/plugins/plugin-1/index.js são manipuladores de eventos que são executados em momentos específicos durante o processamento de solicitação e resposta. Por exemplo, onrequest executa o primeiro byte dos cabeçalhos da solicitação é recebido. Enquanto, onend_response é executado depois que o último byte dos dados de resposta é recebido.

Confira o gerenciador ondata_response. Ele é chamado sempre que um bloco dos dados de resposta é recebido. O importante é saber que os dados de resposta não são necessariamente recebidos de uma só vez. Em vez disso, os dados podem ser recebidos em blocos de tamanho arbitrário.

3. Adicionar os plug-ins à sequência de plug-ins

Continuando com este exemplo, vamos adicionar os plug-ins à sequência de plug-ins no arquivo de configuração do Edge Microgateway (~./edgemicro/config.yaml) da seguinte maneira. A sequência é importante. Ela define a ordem em que os gerenciadores de plug-in são executados.

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

4. Examinar a saída de depuração

Agora, vamos conferir a saída que seria produzida quando esses plug-ins fossem chamados. Há alguns pontos importantes:

  • A sequência de plug-ins em que o arquivo de configuração do Edge Microgateway (~./edgemicro/config.yaml) especifica a ordem em que os manipuladores de eventos são chamados.
  • Os gerenciadores de solicitações são chamados em ordem crescente, ou seja, na ordem em que aparecem na sequência do plug-in (1, 2, 3).
  • Os gerenciadores de resposta são chamados em ordem decrescente: 3, 2, 1.
  • O gerenciador ondata_response é chamado uma vez para cada bloco de dados que chega. Neste exemplo (saída mostrada abaixo), dois blocos são recebidos.

Veja a seguir um exemplo de saída de depuração produzido quando esses três plug-ins estão em uso e uma solicitação é enviada pelo Edge Microgateway. Observe a ordem em que os manipuladores são chamados:

  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

Resumo

Entender a ordem em que os gerenciadores de plug-ins são chamados é muito importante quando você tenta implementar uma funcionalidade de plug-in personalizada, como acumular e transformar dados de solicitação ou resposta.

Lembre-se de que os gerenciadores de solicitação são executados na ordem em que os plug-ins são especificados no arquivo de configuração do Edge Microgateway, e os gerenciadores de resposta são executados na ordem oposta.

Sobre o uso de variáveis globais em plug-ins

Todas as solicitações ao Edge Microgateway são enviadas para a mesma instância de um plug-in. Portanto, o estado de uma segunda solicitação de outro cliente substitui o primeiro. O único local seguro para salvar o estado do plug-in é armazená-lo em uma propriedade no objeto de solicitação ou resposta (cujo ciclo de vida é limitado ao da solicitação).

Reescrever URLs de destino em plug-ins

Adicionado em: v2.3.3

Você pode modificar o URL de destino padrão em um plug-in dinamicamente. Para isso, modifique estas variáveis no código do plug-in: req.targetHostname e req.targetPath.

Adicionado em: v2.4.x

Também é possível substituir a porta de endpoint de destino e escolher entre HTTP e HTTPS. Modifique essas variáveis no código do plug-in: req.targetPort e req.targetSecure. Para escolher HTTPS, defina req.targetSecure como true. Para HTTP, defina como false. Se você definir req.targetSecure como "true", consulte esta conversa para mais informações.

Removido em: v3.3.3

O plug-in de amostra eurekaclient (em inglês) foi removido do Edge Microgateway na v.3.3.3. Consulte as Notas da versão.

A remoção desse recurso não afeta a funcionalidade principal do Edge microgateway nem a reescrita dos URLs de destino. É possível configurar a pesquisa de endpoint dinâmico e substituir as variáveis de destino, como req.targetHostname, req.targetPath, req.targetPort e req.targetSecure no nível do plug-in. Consulte Como reescrever URLs de destino em plug-ins.


Exemplos de plug-ins

Esses plug-ins são fornecidos com sua instalação do Edge Microgateway. Eles podem ser encontrados na instalação do Edge Microgateway:

[prefix]/lib/node_modules/edgemicro/plugins

em que [prefix] é o diretório de prefixo npm, conforme descrito em "Onde o Edge Microgateway está instalado" em Como instalar o Edge Microgateway.

solicitação de acumulação

Esse plug-in acumula blocos de dados do cliente em uma propriedade de matriz anexada ao objeto de solicitação. Quando todos os dados da solicitação são recebidos, a matriz é concatenada em um buffer que é passado para o próximo plug-in na sequência. Esse plug-in precisa ser o primeiro na sequência para que os subsequentes recebam os dados de solicitação 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 resposta

Esse plug-in acumula blocos de dados do destino em uma propriedade de matriz anexada ao objeto de resposta. Quando todos os dados de resposta são recebidos, a matriz é concatenada em um buffer que é passado para o próximo plug-in na sequência. Como esse plug-in opera em respostas, que são processadas na ordem inversa, você precisa posicioná-lo como o último plug-in na sequência.

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 de maiúsculas/minúsculas

As distribuições do Edge Microgateway incluem um plug-in de amostra chamado <microgateway-root-dir>/plugins/header-uppercase. A amostra inclui comentários que descrevem cada um dos gerenciadores de função. Este exemplo faz uma transformação de dados simples da resposta de destino e adiciona cabeçalhos personalizados à solicitação do cliente e à resposta de destino.

Confira o código-fonte 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();
    }

  };

}


transformar-maiúsculas

Este é um plug-in de transformação geral que pode ser modificado para fazer o tipo de transformação que você quiser. Esse exemplo simplesmente transforma os dados de resposta e solicitação em maiú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);
    }

  };

}