Lambda Node.JS Packaging


이제껏 1개의 Node.JS 파일에 npm module을 하나도 사용하지 않은 예제만 살펴보았는데, 실제로 개발할 상황에서는 파일도 여러 개로 나눠서 개발하고 npm module도 많이 사용할 경우가 많습니다. 이렇게 개발한 코드들을 어떻게 Lambda로 올리는지 이번 포스팅에서 살펴보도록 하겠습니다.

Lambda 와 API Gateway 연동 #3까지 구현되어 있다는 가정하에서 진행하겠습니다.

Node.JS 코드에 npm 사용

  • 이전까지 작업한 코드를 index.js란 이름으로 작업할 폴더에 저장
  • npm으로 lodash 설치 : npm install lodash
  • 코드를 아래와 같이 수정
'use strict';

const _ = require('lodash');

function get(userId) {
  return {
    body: { id: userId, name: "test" }
  };
}

function post(userId, header, body) {
  return {
    body: { id: userId, header: header, body: body }
  };
}

const routeMap = {
  '/test': {
    'GET': (event, context) => {
      const userId = _.get(event,'queryStringParameters.id');
      return get(userId);
    },
    'POST': (event, context) => {
      const userId = _.get(event,'queryStringParameters.id');
      const body = JSON.stringify(_.get(event,'body'));
      const header =  event.headers;
      return post(userId, header, body);
    }
  }
};

function router(event, context) {
  const controller = routeMap[event.path][event.httpMethod];

  if(!controller) {
    return {
      body: { Error: "Invalid Path" }
    };
  }

  return controller(event, context);
}

exports.handler = (event, context, callback) => {
   let result = router(event, context);
   callback(null, {body:JSON.stringify(result)});
}

routeMap 내부에 lodash.get 함수를 사용하는 것으로 코드를 변경하였습니다.

  • zip 파일로 압축 : zip -r ./sample.zip ./

Lambda에 zip 파일로 배포

먼저 해당 Lambda 설정으로 이동합니다.

  • Code
    • Code entry type : Upload a .ZIP file 선택
    • Upload 버튼을 눌러서 위에서 생성한 sample.zip을 올림

확인

API Gateway는 변경사항이 없으므로 결과는 3장과 똑같이 나옵니다.

  • GET 요청 : https://.../prod/test?id=2
{"body":{"id":"2","name":"test"}}
  • POST 요청 : URL은 GET과 동일
{
  "body": {
    "id": "2",
    "header": {
      ...
    },
    "body": "\"{\\n  \"id\": \"123\",\\n  \"age\": \"25\"\\n}\""
  }
}

여러 파일을 함께 배포

이미 npm module을 포함하여 베포하였으므로 여러 파일을 묶어서 배포하는게 확인되었지만, 우리가 작성한 소스코드 자체도 나눠서 배포해 보도록 하겠습니다. 위에 작성한 코드를 4개의 파일로 나눠서 올려보겠습니다.

  • index.js
'use strict';

const router = require('./router');

exports.handler = (event, context, callback) => {
   let result = router(event, context);
   callback(null, {body:JSON.stringify(result)});
}
  • router.js
'use strict';

const _ = require('lodash');

const routeMap = {
  '/test': {
    'GET': (event, context) => {
      const userId = _.get(event,'queryStringParameters.id');
      return require('./controllers/test/get')(userId);
    },
    'POST': (event, context) => {
      const userId = _.get(event,'queryStringParameters.id');
      const body = JSON.stringify(_.get(event,'body'));
      const header =  event.headers;
      return require('./controllers/test/post')(userId, header, body);
    }
  }
};

module.exports = (event, context) => {
  const controller = routeMap[event.path][event.httpMethod];

  if(!controller) {
    return {
      body: { Error: "Invalid Path" }
    };
  }

  return controller(event, context);
};
  • /controllers/test/get.js
module.exports = (userId) => {
  return {
    body: { id: userId, name: "test" }
  };
};
  • /controllers/test/post.js
module.exports = (userId, header, body) => {
  return {
    body: { id: userId, header: header, body: body }
  };
};
  • npm으로 lodash 설치 : npm install lodash
  • zip 파일로 압축 : zip -r ./sample.zip ./

위에서와 같은 방법으로 Lambda에 배포 후 확인을 해보면 같은 결과가 출력됩니다.

Lambda에 zip 파일로 배포

먼저 해당 Lambda 설정으로 이동합니다.

  • Code
    • Code entry type : Upload a .ZIP file 선택
    • Upload 버튼을 눌러서 위에서 생성한 sample.zip을 올림

확인

API Gateway는 변경사항이 없으므로 결과는 3장과 똑같이 나옵니다.

  • GET 요청 : https://.../prod/test?id=2
{"body":{"id":"2","name":"test"}}
  • POST 요청 : URL은 GET과 동일
{
  "body": {
    "id": "2",
    "header": {
      ...
    },
    "body": "\"{\\n  \"id\": \"123\",\\n  \"age\": \"25\"\\n}\""
  }
}

마치며…

이번 포스팅에서 알아본 내용들은 다음과 같습니다.

  • Lambda에 여러 파일을 .zip으로 묶어서 함께 배포
    • npm module을 함께 배포
    • 여러 파일로 작성된 소스코드들을 함께 배포

잘못되었거나, 변경된 점, 기타 추가 사항에 대한 피드백은 언제나 환영합니다. - seokjoon.yun@gmail.com

참고

LabmdaNode.JS로 구현하는 내용에 대해서는 아래 3개의 Link를 참고해 주세요.


이 글이 도움이 되셨다면 공감 및 광고 클릭을 부탁드립니다 :)