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 라고 되어있는데 말이죠.