커스텀 플러그인 개발

현재 Apigee Edge 문서가 표시되고 있습니다.
Apigee X 문서로 이동
정보

Edge Micro Gateway v. 3.1.5 이상

대상

이 주제는 커스텀 플러그인을 작성하여 Edge Micro Gateway 기능을 확장하려는 개발자를 대상으로 합니다. 새 플러그인을 작성하려면 자바스크립트 및 Node.js를 사용한 경험이 필요합니다.

커스텀 Edge Micro Gateway 플러그인이란 무엇인가요?

플러그인은 Edge Micro Gateway에 기능을 추가하는 Node.js 모듈입니다. 플러그인 모듈은 일관된 패턴을 따르고 Edge Micro Gateway에 알려진 위치에 저장되므로 자동으로 검색되고 실행될 수 있습니다. Edge Micro Gateway를 설치할 때 사전 정의된 여러 플러그인이 제공됩니다. 여기에는 인증, 급증 저지, 할당량, 분석을 위한 플러그인이 포함됩니다. 이러한 기존 플러그인은 플러그인 사용에 설명되어 있습니다.

커스텀 플러그인을 작성하여 마이크로 게이트웨이에 새로운 기능을 추가할 수 있습니다. 기본적으로 Edge Micro Gateway는 기본적으로 대상 서비스와 변경되지 않은 요청 및 응답을 전달하는 안전한 패스 스루 프록시입니다. 커스텀 플러그인을 사용하면 마이크로 게이트웨이를 통해 전달되는 요청 및 응답과 프로그래매틱 방식으로 상호작용할 수 있습니다.

커스텀 플러그인 코드를 삽입할 위치

커스텀 플러그인 폴더는 Edge Microgateway 설치의 일부로 여기에 포함됩니다.

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

여기서 [prefix]Edge Micro Gateway 설치의 'Edge Micro Gateway가 설치된 위치'에 설명된 npm 프리픽스 디렉터리입니다.

이 기본 플러그인 디렉터리를 변경할 수 있습니다. 플러그인 위치를 참고하세요.

사전 정의된 플러그인 검토

자체 플러그인을 개발하기 전에 요구사항에 맞는 사전 정의된 플러그인이 없는지 확인하는 것이 좋습니다. 이러한 플러그인은 다음 위치에 있습니다.

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

여기서 [prefix]npm 프리픽스 디렉터리입니다. Edge Micro Gateway 설치의 'Edge Microgateway 설치 위치'도 참조하세요.

자세한 내용은 Edge Micro Gateway와 함께 제공되는 사전 정의된 플러그인을 참조하세요.

간단한 플러그인 작성

이 섹션에서는 간단한 플러그인을 만드는 데 필요한 단계를 살펴봅니다. 이 플러그인은 응답 데이터를 'Hello, World!' 문자열로 재정의하고 터미널에 출력합니다.

  1. Edge Micro Gateway가 실행 중인 경우 지금 중지합니다.
    edgemicro stop
    
  2. cd를 커스텀 플러그인 디렉터리에 추가합니다.

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

    여기서 [prefix]Edge Micro Gateway 설치의 'Edge Micro Gateway가 설치된 위치'에 설명된 npm 프리픽스 디렉터리입니다.

  3. response-override라는 새 플러그인 프로젝트를 만들고 여기에 cd를 만듭니다.
    mkdir response-override && cd response-override
    
  4. 새 Node.js 프로젝트를 만듭니다.
    npm init
    
    기본값을 수락하려면 Return 키를 여러 번 누릅니다.
  5. 텍스트 편집기를 사용하여 index.js라는 새 파일을 만듭니다.
  6. 다음 코드를 index.js에 복사하고 파일을 저장합니다.
    '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. 이제 플러그인을 만들었으므로 Edge Microgateway 구성에 추가해야 합니다. $HOME/.edgemicro/[org]-[env]-config.yaml 파일을 엽니다. 여기서 orgenv은 Edge 조직 및 환경 이름입니다.
  8. 아래와 같이 response-override 플러그인을 plugins:sequence 요소에 추가합니다.
          ...
          
          plugins:
            dir: ../plugins
            sequence:
              - oauth
              - response-override
              
          ...
    
  9. Edge Micro Gateway를 다시 시작합니다.
  10. Edge Micro Gateway를 통해 API를 호출합니다. (이 API 호출은 Edge Micro Gateway 설정 및 구성에 설명된 대로 API 키 보안을 사용하여 튜토리얼과 동일한 구성을 설정했다고 가정합니다.
    curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo
    Hello, World!
    

플러그인 분석

다음 Edge Microgateway 샘플 플러그인은 자체 플러그인을 개발할 때 따라야 할 패턴을 보여줍니다. 이 섹션에서 설명하는 샘플 플러그인의 소스 코드는 plugins/header-uppercase/index.js.에 있습니다.

  • 플러그인은 루트 폴더에 package.jsonindex.js가 있는 표준 NPM 모듈입니다.
  • 플러그인은 init() 함수를 내보내야 합니다.
  • init() 함수는 config, logger, stats라는 세 가지 인수를 사용합니다. 이러한 인수는 플러그인 init() 함수 인수에 설명되어 있습니다.
  • init()는 요청의 전체 기간 동안 특정 이벤트가 발생할 때 호출되는 이름이 지정된 함수 핸들러가 있는 객체를 반환합니다.

이벤트 핸들러 함수

플러그인은 이러한 이벤트 핸들러 함수의 일부 또는 전부를 구현해야 합니다. 이러한 함수의 구현은 개발자가 결정합니다. 지정된 함수는 선택사항이며 일반적인 플러그인은 적어도 이러한 함수의 하위 집합을 구현합니다.

요청 흐름 이벤트 핸들러

이러한 함수는 Edge Micro Gateway의 요청 이벤트 시 호출됩니다.

  • onrequest
  • ondata_request
  • onend_request
  • onclose_request
  • onerror_request

onrequest 함수

클라이언트 요청 시작 시 호출됩니다. 이 함수는 Edge Microgateway에서 요청의 첫 번째 바이트가 수신될 때 실행됩니다. 이 함수를 통해 요청 헤더, URL, 쿼리 매개변수, HTTP 메서드에 액세스할 수 있습니다. 정확한 첫 번째 인수 (예: Error 인스턴스)로 next를 호출하면 요청 처리가 중지되고 타겟 요청이 시작되지 않습니다.

예:

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

ondata_request 함수

데이터 청크가 클라이언트에서 수신될 때 호출됩니다. 요청 데이터를 플러그인 시퀀스의 다음 플러그인으로 전달합니다. 시퀀스의 마지막 플러그인에서 반환된 값이 타겟으로 전송됩니다. 아래와 같은 일반적인 사용 사례는 요청 데이터를 대상에 전송하기 전에 변환하는 것입니다.

예:

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

onend_request 함수

모든 요청 데이터가 클라이언트에서 수신되었을 때 호출됩니다.

예:

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

onclose_request 함수

클라이언트 연결이 닫혔음을 나타냅니다. 클라이언트 연결이 불안정한 경우에 이 함수를 사용할 수 있습니다. 이 메서드는 클라이언트와의 소켓 연결이 닫힐 때 호출됩니다.

예:

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

onerror_request 함수

클라이언트 요청을 수신하는 데 오류가 발생하면 호출됩니다.

예:

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

응답 흐름 이벤트 핸들러

이러한 함수는 Edge Micro Gateway의 응답 이벤트 시 호출됩니다.

  • onresponse
  • ondata_response
  • onend_response
  • onclose_response
  • onerror_response

onresponse 함수

타겟 응답 시작 시 호출됩니다. 이 함수는 Edge Micro Gateway가 응답의 첫 번째 바이트를 수신하면 실행됩니다. 이 함수를 통해 응답 헤더 및 상태 코드에 액세스할 수 있습니다.

예:

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


ondata_response 함수

데이터 청크가 대상에서 수신될 때 호출됩니다.

예:

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


onend_response 함수

모든 응답 데이터가 대상에서 수신되었을 때 호출됩니다.

예:

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

onclose_response 함수

대상 연결이 닫혔음을 나타냅니다. 대상 연결이 불안정한 경우에 이 함수를 사용할 수 있습니다. 타겟에 대한 소켓 연결이 닫히면 호출됩니다.

예:

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


onerror_response 함수

타겟 응답을 수신하는 중에 오류가 발생하면 호출됩니다.

예:

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

플러그인 이벤트 핸들러 함수에 대해 알아야 할 사항

플러그인 이벤트 핸들러 함수는 Edge Micro Gateway가 지정된 API 요청을 처리하는 동안 발생하는 특정 이벤트에 대한 응답으로 호출됩니다.

  • 처리가 완료되면 각 init() 함수 핸들러 (ondata_request, ondata_response 등)는 next() 콜백을 호출해야 합니다. next()를 호출하지 않으면 처리가 중지되고 요청이 중단됩니다.
  • next()의 첫 번째 인수는 오류일 수 있으며, 이 경우 요청 처리가 종료됩니다.
  • ondata_onend_ 핸들러는 타겟 또는 클라이언트에 전달할 데이터가 포함된 두 번째 인수로 next()를 호출해야 합니다. 플러그인이 버퍼링 중이고 현재 변환할 데이터가 충분하지 않은 경우 이 인수는 null이 될 수 있습니다.
  • 플러그인의 단일 인스턴스가 모든 요청과 응답을 처리하는 데 사용됩니다. 플러그인이 호출 간에 요청별 상태를 유지하려는 경우 제공된 request 객체 (req)에 추가된 속성에 이 상태를 저장할 수 있습니다. 이 객체의 전체 기간은 API 호출 기간입니다.
  • 모든 오류를 포착하고 오류와 함께 next()를 호출하도록 주의하세요. next() 호출에 실패하면 API 호출이 중단됩니다.
  • 메모리 누수가 발생하지 않도록 주의하세요. 메모리 누수는 Edge Micro Gateway의 전반적인 성능에 영향을 미치고 메모리가 부족하면 비정상 종료될 수 있습니다.
  • 기본 스레드에서 컴퓨팅 집약적인 작업을 수행하지 않고 Node.js 모델을 따라야 합니다. 이는 Edge Micro Gateway의 성능에 부정적인 영향을 미칠 수 있습니다.

플러그인 init() 함수 정보

이 섹션에서는 init() 함수에 전달되는 인수인 config, logger, stats에 대해 설명합니다.

config

Edge Micro Gateway 구성 파일을 Apigee Edge에서 다운로드한 데이터와 병합하여 얻은 구성 데이터는 config이라는 객체에 배치됩니다.

값이 fooparam 구성 매개변수를 response-override라는 플러그인에 추가하려면 default.yaml 파일에 다음을 입력합니다.

response-override:
    param: foo

그런 다음 플러그인 코드에서 다음과 같이 매개변수에 액세스할 수 있습니다.

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

이 경우 플러그인 디버그 출력에 foo가 출력됩니다.

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

하위 객체 config.emgConfigs에서 병합된 마이크로 게이트웨이 구성 및 다운로드한 Apigee Edge 데이터에 액세스할 수 있습니다. 예를 들어 다음과 같이 init 함수에서 이 구성 데이터에 액세스할 수 있습니다.

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

다음은 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

시스템 로거입니다. 현재 사용된 로거는 이러한 함수를 내보냅니다. 여기서 객체는 문자열, HTTP 요청, HTTP 응답 또는 Error 인스턴스일 수 있습니다.

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

stats

요청, 응답, 오류, 마이크로 게이트웨이 인스턴스를 통해 전달되는 요청 및 응답과 관련된 기타 집계된 통계를 보유하는 객체입니다.

  • treqErrors - 오류가 있는 대상 요청의 수
  • treqErrors - 오류가 있는 대상 응답 수입니다.
  • statusCodes - 응답 코드 수가 포함된 객체입니다.
{
  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
  }
  
  • requests - 총 요청 수입니다.
  • 응답 - 총 응답 수입니다.
  • connections - 활성 대상 연결의 수입니다.

next() 함수 정보

모든 플러그인 메서드는 next()를 호출하여 시리즈의 다음 메서드를 계속 처리해야 합니다. 그러지 않으면 플러그인 프로세스가 중단됩니다. 요청 수명 주기에서 호출되는 첫 번째 메서드는 onrequest()입니다. 다음으로 호출할 메서드는 ondata_request() 메서드입니다. 그러나 ondata_request는 POST 요청처럼 요청에 데이터가 포함된 경우에만 호출됩니다. 다음으로 호출되는 메서드는 onend_request()로, 요청 처리가 완료될 때 호출됩니다. onerror_* 함수는 오류가 발생한 경우에만 호출되며 원하는 경우 커스텀 코드로 오류를 처리할 수 있습니다.

요청으로 데이터가 전송되고 ondata_request()가 호출된다고 가정해 보겠습니다. 이 함수는 다음 두 매개변수를 사용하여 next()를 호출합니다.

next(null, data);

규칙에 따라 첫 번째 매개변수는 오류 정보를 전달하는 데 사용되며 그런 다음 체인의 후속 함수에서 처리할 수 있습니다. 잘못된 인수인 null로 설정하면 오류가 없으며 요청 처리가 정상적으로 진행된다는 의미입니다. 이 인수가 참이면 (예: Error 객체) 요청 처리가 중지되고 요청이 대상으로 전송됩니다.

두 번째 매개변수는 요청 데이터를 체인의 다음 함수에 전달합니다. 추가 처리를 하지 않으면 요청 데이터가 API 대상에 변경되지 않은 상태로 전달됩니다. 그러나 이 메서드 내에서 요청 데이터를 수정하고 수정된 요청을 대상에 전달할 수 있습니다. 예를 들어 요청 데이터가 XML이고 대상이 JSON을 예상하는 경우 ondata_request() 메서드에 코드를 추가할 수 있습니다. 이 코드는 (a) 요청 헤더의 Content-Type을 application/json로 변경하고 원하는 방법을 사용하여 요청 데이터를 JSON으로 변환합니다 (예: NPM에서 가져온 Node.js xml2json 변환기를 사용할 수 있음).

어떻게 표시되는지 살펴보겠습니다.

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

이 경우 요청 데이터 (XML로 가정)는 JSON으로 변환되고 변환된 데이터는 next()를 통해 요청 체인의 다음 함수로 전달된 후 백엔드 대상으로 전달됩니다.

다른 디버그 문을 추가하여 디버깅 목적으로 변환된 데이터를 출력할 수 있습니다. 예를 들면 다음과 같습니다.

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

플러그인 핸들러 실행 순서 정보

Edge Micro Gateway용 플러그인을 작성하는 경우 플러그인 이벤트 핸들러가 실행되는 순서를 파악해야 합니다.

Edge Microgateway 구성 파일에서 플러그인 시퀀스를 지정하면 요청 핸들러가 오름차순으로 실행되고 응답 핸들러는 내림차순으로 실행된다는 점이 중요합니다.

다음 예는 이 실행 순서를 이해하는 데 도움이 되도록 설계되었습니다.

1. 간단한 플러그인 3개 만들기

다음 플러그인을 생각해 보세요. 이벤트 핸들러가 호출될 때 콘솔 출력만 실행하면 됩니다.

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

이제 동일한 코드로 plugin-2plugin-3라는 플러그인을 두 개 더 만들어 봅니다 (console.log() 문을 plugin-2plugin-3로 각각 변경).

2. 플러그인 코드 검토

<microgateway-root-dir>/plugins/plugin-1/index.js에서 내보낸 플러그인 함수는 요청 및 응답 처리 중 특정 시간에 실행되는 이벤트 핸들러입니다. 예를 들어 onrequest는 수신된 요청 헤더의 첫 번째 바이트를 실행합니다. 동시에 onend_response는 응답 데이터의 마지막 바이트가 수신된 후에 실행됩니다.

ondata_response 핸들러를 살펴보세요. 응답 데이터 청크가 수신될 때마다 호출됩니다. 응답 데이터가 반드시 한 번에 모두 수신되지는 않는다는 점을 알아야 합니다. 오히려 데이터는 임의의 길이의 청크로 수신될 수 있습니다.

3. 플러그인 시퀀스에 플러그인 추가

이 예시를 계속 진행하면서 다음과 같이 Edge Microgateway 구성 파일 (~./edgemicro/config.yaml)의 플러그인 시퀀스에 플러그인을 추가합니다. 이 시퀀스는 중요합니다. 플러그인 핸들러가 실행되는 순서를 정의합니다.

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

4. 디버그 출력 검토

이제 이러한 플러그인이 호출될 때 생성되는 출력을 살펴보겠습니다. 다음과 같은 몇 가지 중요한 사항을 유의해야 합니다.

  • Edge Micro Gateway 구성 파일(~./edgemicro/config.yaml)의 플러그인 시퀀스는 이벤트 핸들러가 호출되는 순서를 지정합니다.
  • 요청 핸들러는 오름차순 (플러그인 시퀀스에 표시되는 순서 -- 1, 2, 3)으로 호출됩니다.
  • 응답 핸들러는 3, 2, 1의 내림차순으로 호출됩니다.
  • ondata_response 핸들러는 도착하는 데이터 청크마다 한 번씩 호출됩니다. 이 예시 (아래 출력 참고)에서는 두 개의 청크가 수신됩니다.

다음은 이 세 가지 플러그인을 사용 중이고 요청이 Edge Microgateway를 통해 전송될 때 생성되는 디버그 출력 샘플입니다. 핸들러가 호출되는 순서를 확인합니다.

  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

요약

요청 또는 응답 데이터의 누적 및 변환과 같은 맞춤 플러그인 기능을 구현하려고 할 때는 플러그인 핸들러가 호출되는 순서를 이해하는 것이 매우 중요합니다.

요청 핸들러는 Edge Micro Gateway 구성 파일에 플러그인이 지정된 순서대로 실행되고 응답 핸들러는 반대 순서로 실행된다는 점에 유의하세요.

플러그인에서 전역 변수 사용 정보

Edge Micro Gateway에 대한 모든 요청은 플러그인의 동일한 인스턴스로 전송되므로 다른 클라이언트의 두 번째 요청 상태가 첫 번째 요청을 덮어씁니다. 플러그인 상태를 저장하기에 안전한 유일한 위치는 요청 또는 응답 객체의 속성에 상태를 저장하는 것입니다. 이 객체의 수명은 요청의 수명으로 제한됩니다.

플러그인에서 대상 URL 재작성

추가된 위치: v2.3.3

플러그인 코드에서 req.targetHostnamereq.targetPath 변수를 수정하여 플러그인의 기본 타겟 URL을 동적으로 재정의할 수 있습니다.

추가된 위치: v2.4.x

대상 엔드포인트 포트를 재정의하고 HTTP와 HTTPS 중에서 선택할 수도 있습니다. 플러그인 코드에서 req.targetPortreq.targetSecure 변수를 수정합니다. HTTPS를 선택하려면 req.targetSecuretrue로 설정하고, HTTP의 경우 false로 설정합니다. req.targetSecure를 true로 설정한 경우 자세한 내용은 이 토론 스레드를 참조하세요.

eurekaclient라는 샘플 플러그인이 Edge Micro Gateway에 추가되었습니다. 이 플러그인은 req.targetPort 및 req.targetSecure 변수를 사용하는 방법을 보여주고, Edge Micro Gateway가 Eureka를 서비스 엔드포인트 카탈로그로 사용하여 동적 엔드포인트 조회를 수행하는 방법을 보여줍니다.


샘플 플러그인

이러한 플러그인은 Edge Micro Gateway 설치 시 제공됩니다. 다음 Edge Micro Gateway 설치에서 이를 찾을 수 있습니다.

[prefix]/lib/node_modules/edgemicro/plugins

여기서 [prefix]Edge Micro Gateway 설치의 'Edge Micro Gateway가 설치된 위치'에 설명된 npm 프리픽스 디렉터리입니다.

누적 요청

이 플러그인은 클라이언트의 데이터 청크를 요청 객체에 연결된 배열 속성에 누적합니다. 모든 요청 데이터가 수신되면 배열은 버퍼에 연결되어 시퀀스의 다음 플러그인으로 전달됩니다. 이 플러그인은 후속 플러그인이 누적된 요청 데이터를 수신하도록 시퀀스의 첫 번째 플러그인이어야 합니다.

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

    }

  };

}

누적-응답

이 플러그인은 타겟의 데이터 청크를 응답 객체에 연결된 배열 속성에 누적합니다. 모든 응답 데이터가 수신되면 배열은 버퍼에 연결되어 시퀀스의 다음 플러그인으로 전달됩니다. 이 플러그인은 역순으로 처리되는 응답에 대해 작동하므로 순서에서 마지막 플러그인으로 배치해야 합니다.

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

  };

}

header-uppercase 플러그인

Edge Microgateway 배포에는 <microgateway-root-dir>/plugins/header-uppercase라는 샘플 플러그인이 포함되어 있습니다. 샘플에는 각 함수 핸들러를 설명하는 주석이 포함되어 있습니다. 이 샘플은 대상 응답의 몇 가지 간단한 데이터 변환을 수행하고 클라이언트 요청 및 대상 응답에 커스텀 헤더를 추가합니다.

다음은 <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();
    }

  };

}


변환-대문자

이는 원하는 모든 종류의 변환을 실행하도록 수정할 수 있는 일반 변환 플러그인입니다. 이 예에서는 단순히 응답과 요청 데이터를 대문자로 변환합니다.

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

  };

}