프로젝트 구조
1. 변경 사항
Extension v1.0.12
버전부터 사용자의Desktop/Laptop
에 설치된Node.js
버전이 Node.js 18 버전 미만일 경우 실행되지 않습니다.Application Lambda
또는Long-Term Service
의 기본 프레임워크가 @rdk/lambda → @cals-framework/lambda 로 변경되었습니다.- 기존
Application Lambda
또는Long-Term Service
를 수정 및 배포할 경우 프레임워크 변경에 따라 다음 작업을 진행해야 합니다.(※ 상세 변경 사항 및 방법은 이후 변경 가이드 내용 참고)
index.js → app.js
로 파일명 변경 및 소스 내용 변경controller.js
내부method
명 변경/config/
폴더 하위의json
파일 형식의 데이터를js
파일로 변경- 프레임워크 변경으로 인한 상속 파일 변경
(LambdaBaseConstant, ApplicationLambdaException, LambdaBaseLib, ApplicationLambdaBaseModel, LambdaBaseUtil, BaseHandler, BaseController, BaseService, BaseDAO)
Extension – localExplorer
의Migration
버튼 클릭 후Deploy
진행
2. 폴더 구조 설명
번호 | 폴더 명 | 설명 |
---|---|---|
1 | config | 실행 환경 설정 값들을 정의하는 공간입니다. |
2 | constant | 프로젝트 내 사용하는 상수값들을 모아놓은 폴더입니다. |
3 | exception | Exception 정의 클래스 파일들을 모아놓은 공간입니다. |
4 | lib | 외부 라이브러리를 사용하는 클래스 파일들을 모아놓은 공간입니다. |
5 | model | Model 정의 클래스 파일들을 모아놓은 공간입니다. |
6 | query | Query XML 파일들을 모아놓은 곳입니다. |
7 | src | 프로젝트에서 사용되는 업무적 소스를 모아놓은 폴더입니다. |
8 | util | 프로젝트에서 공통으로 사용될 소스들을 관리하는 폴더입니다. |
3. 파일 구조 설명
- 환경변수 값에 따라 자동으로
Local
환경과 운영 환경을 구분하기 위한 파일입니다.
/config/projectBaseConfig.js
const { ProjectBaseConfigDev } = require('./projectBaseConfigDev')
const { ProjectBaseConfigProd } = require('./projectBaseConfigProd')
module.exports.ProjectBaseConfig = process.env.NODE_ENV !== 'production' ? ProjectBaseConfigDev : ProjectBaseConfigProd
Local
환경에서 디버깅을 위한 환경 설정 파일입니다.
/config/projectBaseConfigDev.js
'use strict'
const { LambdaBaseConfig, DB_CONNECTION_TYPE, LogLevel, NODE_ENV_TYPE } = require('@cals-framework/lambda')
const { resolve } = require('path')
/**
* ProjectBaseConstant class
*
* @class
*/
class ProjectBaseConfigDev extends LambdaBaseConfig {
/**
* 생성자로 상수 변수 생성
*
* @constructor
*/
// 여기서부터 수정 가능 구역
constructor() {
super()
this.NODE_ENV = NODE_ENV_TYPE.DEVELOPMENT
this.OBJ_MAPPER.path.push(resolve(__dirname, '../query/mysql/mysql.xml'))
this.OBJ_MAPPER.namespace.mysql = 'mysql'
this.Logger.LEVEL = LogLevel.DEBUG
this.Logger.ParamEnabled = false
this.Logger.ResultEnabled = false
this.Logger.DBLogEnabled = true
this._DB.ENGINE = 'mysql'
this._DB.CONNECTION_TYPE = DB_CONNECTION_TYPE.CONFIG
this._DB.HOST = '{{dbHost}}'
this._DB.USER = '{{dbUser}}'
this._DB.PASSWORD = '{{dbPassword}}'
this._DB.SCHEMA = '{{dbSchema}}'
}
}
module.exports.ProjectBaseConfigDev = ProjectBaseConfigDev
- 운영 환경에서 동작하기 위한 환경 설정 파일입니다.(Support Key: YES 상태에서만 표시됩니다.)
/config/projectBaseConfigProd.js
'use strict'
const { LambdaBaseConfig, DB_CONNECTION_TYPE, LogLevel, NODE_ENV_TYPE } = require('@cals-framework/lambda')
const { resolve } = require('path')
console.log(`process.env.AWS_REGION: ${process.env.AWS_REGION}`)
/**
* ProjectBaseConstant class
*
* @class
*/
class ProjectBaseConfigProd extends LambdaBaseConfig {
/**
* 생성자로 상수 변수 생성
*
* @constructor
*/
// 여기서부터 수정 가능 구역
constructor() {
super()
this.NODE_ENV = NODE_ENV_TYPE.PRODUCTION
this.OBJ_MAPPER.path.push(resolve(__dirname, '../query/mysql/mysql.xml'))
this.OBJ_MAPPER.namespace.mysql = 'mysql'
this.Logger.LEVEL = LogLevel.DEBUG
this.Logger.ParamEnabled = false
this.Logger.ResultEnabled = false
this.Logger.RdkLogEnabled = false
this.Logger.DBLogEnabled = true
this._DB.ENGINE = 'mysql'
this._DB.CONNECTION_TYPE = DB_CONNECTION_TYPE.SECRETS_MANAGER
this._DB.HOST = 'demo'
this._DB.USER = ''
this._DB.PASSWORD = ''
this._DB.SCHEMA = ''
this._CACHE_DB.CONNECTION_TYPE = DB_CONNECTION_TYPE.CONFIG
this._CACHE_DB.ENGINE = ''
this._CACHE_DB.HOST = '127.0.0.1'
this._CACHE_DB.PORT = 6379
}
}
module.exports.ProjectBaseConfigProd = ProjectBaseConfigProd
- 프로젝트 내부에서 사용하는 상수들을 정리하는 파일입니다.
/constant/projectBaseConstant.js
'use strict'
/**
* @fileoverview 상수변수들을 모아놓은 파일
*/
/**
* ProjectBaseConstant
* @module ProjectBaseConstant
* @example
* const ProjectBaseConstant = require('../constant/projectBaseConstant')
* const clsProjectBaseConstant = new ProjectBaseConstant()
*/
const { AppLambdaBaseConstant } = require('@cals-framework/lambda')
/**
* ProjectBaseConstant class
* @class
*/
module.exports = class ProjectBaseConstant extends AppLambdaBaseConstant {
/**
* 생성자로 상수 변수 생성
* @constructor
*/
// 여기서부터 수정 가능 구역
constructor () {
super()
}
static ERROR_MESSAGE = {
NO_AFFECTED_QUERY: 'NO AFFECTED QUERY'
}
static QUERY_INFO = {
selectTest1: {
name: 'selectTest1',
type: this.ORM_QUERY_TYPE.SELECT
}
}
}
- 프로젝트 내부에서 사용할 외부 라이브러리를 포함한 클래스를 작성하는 파일입니다.
/lib/lambdaLib.js
'use strict'
/**
* @fileoeverview 샘플 Library 모듈
* lambdaLib.js
*/
const os = require('os')
const { LambdaBaseLib } = require('@cals-framework/lambda')
/**
* Lambda 샘플 library 모듈
* @module LambdaLib
* @example
* const RdkLambdaLib = require('./lambdaLib.js)
* const clsRdkLambdaLib = new RdkLambdaLib()
* @desc Lambda 샘플 library 모듈
*/
module.exports = class LambdaLib extends LambdaBaseLib {
/**
* 생성자로 Library 객체 생성
* @constructs
* @param
*/
constructor () {
super()
this.homeDir = os.homedir()
this.hostName = os.hostname()
this.getTempDir = getTempDir
}
/**
* getTempDir 함수
* @function
* @param
* @desc temp Directory 반환
*/
getTempDir() {
return this.path.resolve(os.tmpdir())
}
}
- 프로젝트 내에서 사용할
Model
객체를 정의하는 파일입니다.
/model/lambdaModel.js
'use strict'
/**
* @fileoeverview 샘플 Model 모듈
* lambdaModel.js
*/
const { ApplicationLambdaBaseModel } = require('@cals-framework/lambda')
/**
* 샘플 Model 모듈
* @module LambdaModel
* @example
* const LambdaModel = require('./lambdaModel.js')
* const clsLambdaModel = new LambdaModel()
* @desc 샘플 Model 모듈
*/
class SampleAddDataModel extends ApplicationLambdaBaseModel {
constructor () {
super()
this.sampleName = ''
this.sampleDesc = ''
}
}
exports.SampleAddDataModel = SampleAddDataModel
class SampleUpdateDataModel extends ApplicationLambdaBaseModel {
constructor () {
super()
this.sampleName = ''
this.sampleDesc = ''
}
}
exports.SampleUpdateDataModel = SampleUpdateDataModel
MVC
패턴에 따라 전달 받은 이벤트 값에 대한 유효성 검사 및 기본값 설정 등의 소스를 작성하는 파일입니다.
/src/controller.js
'use strict'
const { BaseController, CompareUtility, ParameterNonExistException, calsLogger } = require('@cals-framework/lambda')
const Service = require('./service')
module.exports = class Controller extends BaseController {
constructor ({ event, context }) {
super({ event, context })
this.event = event
this.context = context
this.calsContext.serviceContext === undefined
? this.clsService = new Service()
: typeof this.calsContext.serviceContext !== 'undefined'
? this.calsContext.serviceContext = new Service()
: this.clsService = this.calsContext.serviceContext
}
async process () {
calsLogger.param(this.event, this.context)
this.objReturn = await this.clsService.runMethod({ objRequestParams: this.objRequestParams, objReturn: this.objReturn })
calsLogger.result(this.objReturn)
return this.objReturn
}
}
- 비즈니스 로직을 수행하는 함수를 작성하는 파일입니다.
/src/service.js
'use strict'
const { BaseService, calsLogger } = require('@cals-framework/lambda')
const { NoAffectedDataException } = require('../exception/lambdaException')
const ProjectBaseConstant = require('../constant/projectBaseConstant')
const DAO = require('./dao')
module.exports = class Service extends BaseService {
constructor () {
super()
this.calsContext.daoContext === undefined
? this.clsDAO = new DAO()
: typeof this.calsContext.daoContext !== 'undefined'
? this.calsContext.daoContext = new DAO()
: this.clsDAO = this.calsContext.daoContext
}
async runMethod ({ objRequestParams, objReturn }) {
calsLogger.param(objRequestParams)
// 1. 데이터 등록 모델 생성
const SampleAddDataModel = require('../model/lambdaModel').SampleAddDataModel
const objSampleAddDataModel = new SampleAddDataModel()
// 2. 데이터 등록 모델에 데이터 등록
objSampleAddDataModel.sampleName = objRequestParams.sampleName
objSampleAddDataModel.sampleDesc = objRequestParams.sampleDesc
// 3. 데이터 입력
const objAddReturn = await this.clsDAO.addData({ objDAOParams: objSampleAddDataModel, objReturn })
if (objAddReturn.affectedRows === 0) {
throw new NoAffectedDataException(ProjectBaseConstant.ERROR_MESSAGE.NO_AFFECTED_QUERY)
}
calsLogger.result(objReturn)
return objReturn
}
// 여기까지 수정 가능 구역
}
- 데이터베이스에 접속하여 SQL을 실행하는 파일입니다.
/src/dao.js
'use strict'
const { ApplicationDAO, calsLogger } = require('@cals-framework/lambda')
const ProjectBaseConstant = require('../constant/projectBaseConstant')
module.exports = class DAO extends ApplicationDAO {
// 여기서부터 수정 가능 구역
async addData ({ objDAOParams, objReturn }) {
calsLogger.param(objDAOParams)
const objDAOReturn = await this.insert({
sQueryId: 'insertData',
objParam: objDAOParams,
objReturn
})
calsLogger.result(objDAOReturn)
return objDAOReturn
}
}
- 프로젝트에서 유틸리티성으로 작성되는 소스들을 모아놓은 파일입니다.
/util/rdkProjectBaseUtil.js
'use strict'
/**
* @fileoeverview 샘플 Util 모듈
* lambda util Base 모듈
*/
const { RdkLambdaBaseUtil } = require('@cals-framework/lambda')
const LambdaLib = require('../lib/lambdaLib')
const clsLambdaLib = new LambdaLib()
/**
* 샘플 Util 모듈
* @module RdkProjectBaseUtil
* @example
* const RdkProjectBaseUtil = require('./rdkProjectBaseUtil.js')
* const clsRdkProjectBaseUtil = new RdkProjectBaseUtil()
* @desc 샘플 Util 모듈
*/
/**
* 샘플 Util 모듈
* @class
*/
module.exports = class RdkProjectBaseUtil extends RdkLambdaBaseUtil {
constructor () {
super()
this.getOsInfo = getOsInfo
}
}
/**
* 샘플 OS 정보 반환 함수
* @function
* @desc OS 정보 반환 Util 함수
*/
const getOsInfo = () => {
return {
hostName: clsLambdaLib.hostName,
homeDir: clsLambdaLib.homeDir,
tmpDir: clsLambdaLib.getTempDir()
}
}
Lambda
프로젝트가 실행되기 위한Handler
를 지정하는 파일입니다.
/app.js
'use strict'
const { BaseHandler, calsLogger } = require('@cals-framework/lambda')
const { ProjectBaseConfig } = require('./config/projectBaseConfig')
const Controller = require("./src/controller")
class LambdaHandler extends BaseHandler {
process(event, context) {
calsLogger.debug('Project Start')
return Promise.resolve(new Controller({ event, context }).handle())
}
}
exports.handler = new LambdaHandler(new ProjectBaseConfig()).handle
4. Framework Context
- Framework Utility
클래스명 | 설명 |
---|---|
CompareUtility | 값들의 비교 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility |
ConvertUtility | 값의 변환 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility |
RandomUtility | Random하게 정수를 반환하는 등의 Random관련하여, 자주 쓰이는 함수들을 모아놓은 Utility |
StringUtility | String 타입 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility |
FsUtility | File System 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility |
// 구조 분해 방식
const { calsLogger, CompareUtility, ConvertUtility, RandomUtility, StringUtility, FsUtility } = require('@cals-framework/lambda')
// 변수 할당 방식
const CompareUtility = require('@cals-framework/lambda').CompareUtility
const ConvertUtility = require('@cals-framework/lambda').ConvertUtility
const RandomUtility = require('@cals-framework/lambda').RandomUtility
const StringUtility = require('@cals-framework/lambda').StringUtility
const FsUtility = require('@cals-framework/lambda').FsUtility
// calsLogger
calsLogger.debug(“debug log..”)
// => 2024.01.12.T08:46:18.863 [DEBUG] - [PROJECT] debug log..
// 개발자가 로그를 통한 디버깅을 원하는 경우 사용
calsLogger.param(“param log..”)
// => 2024.01.12.T08:46:18.863 [PARAM] - [PROJECT] param log..
// 파라미터를 확인하기 위해 사용
calsLogger.result(“result log..”)
// => 2024.01.12.T08:46:18.863 [RESULT] - [PROJECT] result log..
// 함수의 리턴값 등을 확인하기 위해 사용
calsLogger.error(“error log..”)
// => 2024.01.12.T08:46:18.863 [ERROR] - [PROJECT] error log..
// 에러 로그를 남길 경우 사용
// CompareUtility
CompareUtility.isEmpty(null) // => Return true
CompareUtility.isNotEmpty(null) // => Return false
// ConvertUtility
ConvertUtility.convertCharToBool('1') // => Return true
ConvertUtility.convertNullToEmpty(null) // => Return ''
ConvertUtility.convertStringToInteger('123') // => Return 123
//RandomUtility
RandomUtility.getRandomInt(0, 9) // => Randomly returns a value between 0 and 9
RandomUtility.getUuid() // => Return a 32-digit identifier
// StringUtility
StringUtility.slash('C:\test\path') // => Return 'C:/test/path'
StringUtility.isNonAscii('안녕하세요') // => Return true
StringUtility.lpad('abc', 10, '0') // => Return '000000abc'
StringUtility.rpad('abc', 10, '0') // => Return 'abc000000'
StringUtility.nextLetter('a') // => Return 'b'
StringUtility.getCharSeq().getCharByIndex(27) // => Returns a unique sequence of alphabetic characters based on an index
// FsUtility
FsUtility.existsPath('/temp') // => Return true
FsUtility.writeFile('/temp/file1.txt', 'Hello World')
FsUtility.writeFileAsync('/temp/file2.txt', 'Sample File')
.then(() =>{
console.log('Write Complete!')
})
.catch((err) => {
console.err(`What happens: ${err}`)
})
FsUtility.readDirectory('/temp') // => Return ['file1.txt', 'file2.txt']
FsUtility.readFile('/temp/file1.txt') // => Return 'Hello World'
FsUtility.rmASync('/temp/file2.txt')
.then(() => {
console.log('File Removed.')
})
.catch((err) => {
console.error(`What happens: ${err}`)
})
FsUtility.createDirectory('/temp/newDir')
- Exception
Exception명 | 설명 |
---|---|
AlreadyExistException | 데이터가 이미 존재할 경우 발생하는 에러 클래스 |
DataSQLException | SQL 작업 수행 중 문제가 발생하는 에러 클래스 |
InvalidRequestException | 유효하지 않은 요청이 들어왔을 때 발생하는 에러 클래스 |
MultiDataSelectException | 의도하지 않게 다중의 데이터가 조회되었을 경우 발생하는 에러 클래스 |
NoDataException | 요청 전문 또는 DB 데이터 조회 결과, 데이터가 존재하지 않을 경우 발생하는 에러 클래스 |
OperationFailException | 특정 작업을 수행하던 중 문제가 발생하는 에러 클래스 |
ParameterNonExistException | 요청 전문에 특정 파라미터가 존재하지 않을 경우 발생하는 에러 케이스 |
ApplicationLambdaException | 프레임워크 내부에서 사용되는 에러 케이스 |
WrongConfigException | |
CalsSdkExecuteException | |
LambdaBaseException | |
DBConnectionException | |
NoPreferenceException | |
LockObjectException |
// 구조 분해 할당 방식
const { AlreadyExistException } = require('@cals-framework/lambda')
throw new AlreadyExistException()
// 변수 할당 방식
const DataSQLException = require('@cals-framework/lambda').DataSQLException
throw new DataSQLException()