Skip to content

프로젝트 구조

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 – localExplorerMigration 버튼 클릭 후 Deploy 진행

2. 폴더 구조 설명

Alt text

번호폴더 명설명
1config실행 환경 설정 값들을 정의하는 공간입니다.
2constant프로젝트 내 사용하는 상수값들을 모아놓은 폴더입니다.
3exceptionException정의 클래스 파일들을 모아놓은 공간입니다.
4lib외부 라이브러리를 사용하는 클래스 파일들을 모아놓은 공간입니다.
5modelModel 정의 클래스 파일들을 모아놓은 공간입니다.
6queryQuery XML 파일들을 모아놓은 곳입니다.
7src프로젝트에서 사용되는 업무적 소스를 모아놓은 폴더입니다.
8util프로젝트에서 공통으로 사용될 소스들을 관리하는 폴더입니다.

3. 파일 구조 설명

  1. 환경변수 값에 따라 자동으로 Local 환경과 운영 환경을 구분하기 위한 파일입니다.

/config/projectBaseConfig.js

const { ProjectBaseConfigDev } = require('./projectBaseConfigDev')
const { ProjectBaseConfigProd } = require('./projectBaseConfigProd')

module.exports.ProjectBaseConfig = process.env.NODE_ENV !== 'production' ? ProjectBaseConfigDev : ProjectBaseConfigProd
  1. 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
  1. 운영 환경에서 동작하기 위한 환경 설정 파일입니다.(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
  1. 프로젝트 내부에서 사용하는 상수들을 정리하는 파일입니다.

/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
   }
 }
}
  1. 프로젝트 내부에서 사용할 외부 라이브러리를 포함한 클래스를 작성하는 파일입니다.

/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())
 }
}
  1. 프로젝트 내에서 사용할 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
  1. 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
 }
}
  1. 비즈니스 로직을 수행하는 함수를 작성하는 파일입니다.

/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
 }
 // 여기까지 수정 가능 구역
}
  1. 데이터베이스에 접속하여 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
 }
}
  1. 프로젝트에서 유틸리티성으로 작성되는 소스들을 모아놓은 파일입니다.

/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()
 }
}
  1. 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

  1. Framework Utility
클래스명설명
CompareUtility값들의 비교 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility
ConvertUtility값의 변환 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility
RandomUtilityRandom하게 정수를 반환하는 등의 Random관련하여, 자주 쓰이는 함수들을 모아놓은 Utility
StringUtilityString 타입 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility
FsUtilityFile 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')
  1. Exception
Exception명설명
AlreadyExistException데이터가 이미 존재할 경우 발생하는 에러 클래스
DataSQLExceptionSQL 작업 수행 중 문제가 발생하는 에러 클래스
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()