AWS, Lambda + API Gateway 를 이용한 RESETful API 개발 #2
앞선 포스트에서 기본적인 Lambda Function 을 만들었고, 외부와 통신할 수 있는 인터페이스. API Gateway 를 생성해 랑데뷰함으로서, ‘나 살아있어요!’ 를 성공적으로 전달했다. 이제 한걸음 더 RDS/Aurora 와 연결해 볼 차례다.
AWS Lambda 의 가장 큰 장점은 ‘확장성’ 이다. 내가 선택한 언어에 라이브러리를 설치함으로서, 기능을 편리하게 확장할 수 있다. “AWS, Lambda + API Gateway 를 이용한 RESETful API 개발 #2” 의 목표는 사용자의 요청을 받아(API Gateway) Lambda 에서 선언한 함수(Lambda Function)가 데이터베이스(RDS/Aurora)에 접근해 상호 적용하는 구조 구현이다.
앞서 Lambda Function 의 언어로 NodeJS 를 선택했다. NodeJS 에서 MySQL 을 사용하려면 MySQL 라이브러리가 필요하다. 안타깝게도 Lambda 코드-에디터는 “npm install”과 같은 명령어 실행이 불가하기 때문에, 로컬에 필요한 라이브러리를 설치하고 Lambda 에 업로드해야 한다. 즉, 로컬에 NodeJS 가 설치 되어 있어야 한다.
MySQL 라이브러리 설치 및 코딩
Lambda에 업로드 할 기본 환경을 로컬에 구축한다. node_modules 폴더만 압축해 등록하고, 코드-에디터로 코딩해도 되지만, 최소한의 코드는 로컬에서 작업하고 업로드하는게 여러모로 편리하다. (당연하지만, VSCode 같은 에디터가 사용성이 훨신 좋기 때문이다)
package.json 만들기
PS C:\Works\Lambda> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.
See `npm help json` for definitive documentation on these fields
and exactly what they do.
Use `npm install ` afterwards to install a package and
save it as a dependency in the package.json file.
Press ^C at any time to quit.
package name: (lambda) onelabs-npd-connector
version: (1.0.0) 0.0.1
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to C:\Works\Lambda\package.json:
{
"name": "onelabs-npd-connector",
"version": "0.0.1",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Is this OK? (yes) yes
MySQL 연결을 위한 라이브러리를 설치한다.
PS C:\Works\Lambda> npm install mysql --save npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN [email protected] No description npm WARN [email protected] No repository field. + [email protected] added 11 packages from 15 contributors and audited 13 packages in 1.541s found 0 vulnerabilities
MySQL 의 접속 정보를 보관하고 있는 설정 파일, config.json 을 만든다. 복수의 접속 정보를 사용하는 경우 코드가 복잡해 지기 때문이다.
config.json
{
"npd":{
"host":"mtlabs.rds.amazonaws.com",
"user":"username",
"password":"password",
"database":"databasename"
}
}
‘로컬’에서 실행 할 수 있는 코드를 먼저 만들자. node 로 직접 실행 가능한 구조여야 한다. 내용은 간단하다. MySQL 에 접속 여부를 확인할 수 있는 ping (SELECT 1)에 대한 응답에 따라 데이터베이스 상태를 확인할 수 있다.
local.js
const mysql = require('mysql');
const config = require('./config.json');
const mysqlPool = mysql.createPool ({
host : config.npd.host,
user : config.npd.user,
password: config.npd.password,
database: config.npd.database,
connectionLimit : 60
});
const createResponse = (status, body) => ({
statusCode: status,
body: JSON.stringify(body)
});
mysqlPool.getConnection(function(err, connection){
if(err !== null)
return console.log(createResponse(500, {message: err}));
connection.query('SELECT 1 AS RESULT', function(error,results,field) {
connection.release();
if(error !== null)
return console.log(createResponse(500, {message: error}));
console.log(createResponse(200, {message: results[0].RESULT}));
});
});
실행결과
# 문제가 없다면 200 이 리턴될 것이다.
PS C:\Works\Lambda> node .\index.js
{ statusCode: 200, body: '{"message":1}' }
# 어떠한 문제가 있다면 에러 메시지와 함께 500이 리턴된다.
PS C:\Works\Lambda> node .\index.js
{ statusCode: 500,
body:
'{"message":{"code":"ER_PARSE_ERROR","errno":1064,"sqlMessage":"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\\"SELECT 1 AS RESULT\' at line 1","sqlState":"42000","index":0,"sql":"\\"SELECT 1 AS RESULT"}}' }
Lambda 에 등록할 파일을 만든다. 기본적인 구조는 같지만, 핸들러를 추가하고, Lambda 를 위한 변수를 추가한다. 이 코드는 핸들러를 호출하지 않기 때문에 로컬에서 실행할 경우 어떠한 값도 출력하지 않는다.
index.js
const mysql = require('mysql');
const config = require('./config.json');
const mysqlPool = mysql.createPool ({
host : config.npd.host,
user : config.npd.user,
password: config.npd.password,
database: config.npd.database,
connectionLimit : 60
});
const createResponse = (status, body) => ({
statusCode: status,
body: JSON.stringify(body)
});
exports.handler = function(event, context, callback){
context.callbackWaitsForEmptyEventLoop = false;
mysqlPool.getConnection(function(err, connection){
if(err !== null)
return console.log(createResponse(500, {message: err}));
connection.query('SELECT 1 AS RESULT', function(error,results,field) {
connection.release();
if(error !== null)
return callback(null, createResponse(500, {message: error}));
callback(null, createResponse(200, {message: results[0].RESULT}));
});
});
};
작업이 완료 되었다면 모듈(node_modules)과 작업한 파일 (config.json, index.js)을 zip 파일로 압축하자.

Lambda 코드 업로드 및 테스트
AWS Lambda Console 을 통해 zip 파일을 등록하면 로컬에서 작업했던 내용이 코드-에디터에 표시된다. 만약 10MB 이상의 파일을 등록할 경우 Timeout 이 발생하는 경우가 있으니, S3 에 올려 URL 을 입력해 등록하는 방법이 있다.

등록된 코드를 테스트해보자. 테스트 방법은 이전 포스트와 같다. 문제가 없다면 message 는 1이 회신될 것이다.

이제 API Request 및 RDS 까지 연결되는 작업이 완료됐다. 조금만 응용한다면 다양한 방식으로 API 를 구현 및 사용 가능하다는거. 그리고 아주 쉽다는 것. 이 다음글에서는 API Gateway 의 기능 확장을 다뤄보고자 한다.



local.js 오타인가 보네요. 아래는 index.js 라고 되어있는데 말이죠.