Skip to content

프로젝트 구조

폴더 구조 설명

Alt text

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

파일 구조 설명

1. config

/projectBaseConfigDev.js : Local 환경에서 디버깅을 위한 환경 설정 파일입니다.

 "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";

   // log의 출력 범위를 조절 할 수 있는 변수
   this.Logger.LEVEL = LogLevel.DEBUG;
   // calsLogger.param의 활성 여부를 조절하는 변수
   this.Logger.ParamEnabled = false;
   // calsLogger.result 활성 여부를 조절하는 변수
   this.Logger.ResultEnabled = false;
      // query 로깅 활성 여부를 조절하는 변수
   this.Logger.DBLogEnabled = true;


   this._DB.ENGINE = "mysql";
      // 해당 커넥션은 개발용으로 사용되는 커넥션입니다.
   this._DB.CONNECTION_TYPE = DB_CONNECTION_TYPE.CONFIG;
      // 테스트용으로 사용할 DB의 host를 입력합니다. (일반적으로 로컬DB는 127.0.0.1 을 사용합니다.)
   this._DB.HOST = "{{dbHost}}";
      // 테스트용으로 사용할 DB의 user name을 입력합니다. (일반적으로 로컬DB는 root를 사용합니다.)
   this._DB.USER = "{{dbUser}}";
      // 테스트용으로 사용할 DB의 user password를 입력합니다.
   this._DB.PASSWORD = "{{dbPassword}}";
      // 테스트용으로 사용할 DB의 schema를 입력합니다.
   this._DB.SCHEMA = "{{dbSchema}}";
 }
}
module.exports.ProjectBaseConfigDev = ProjectBaseConfigDev;

2. 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
   }
 }
}

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

4. model

/lambdaModel.js : 프로젝트 내에서 사용할 Model 객체를 정의하는 파일입니다.

'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

5. src

/controller.js : MVC 패턴에 따라 전달 받은 이벤트 값에 대한 유효성 검사 및 기본값 설정 등의 소스를 작성하는 파일입니다.

'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)

   // Todo : 파라미터 유효성 체크,세션 체크
   this.objRequestParams.sampleName = 'test1'
   this.objRequestParams.sampleDesc = 'test1'
   if (CompareUtility.isEmpty(this.objRequestParams.sampleName)) {
     throw new ParameterNonExistException('sampleName')
   }
   if (CompareUtility.isEmpty(this.objRequestParams.sampleDesc)) {
     throw new ParameterNonExistException('sampleDesc')
   }

   this.objReturn = await this.clsService.runMethod({ objRequestParams: this.objRequestParams, objReturn: this.objReturn })

   calsLogger.result(this.objReturn)
   return this.objReturn
 }
}

/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
 }
 // 여기까지 수정 가능 구역
}

/dao.js : 데이터베이스에 접속하여 SQL을 실행하는 파일입니다.

'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
 }
}

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

7. app.js

Lambda 프로젝트가 실행되기 위한 Handler를 지정하는 파일입니다.

'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

Framework Context

  1. logger & Utility
클래스명설명
calsLoggerLambda Framework에서 제공하는 Logger 객체
CompareUtility값들의 비교 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility
ConvertUtility값의 변환 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility
RandomUtilityRandom하게 정수를 반환하는 등의 Random 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility
StringUtilityString 타입 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility
FsUtilityFile System 관련하여, 자주 쓰이는 함수들을 모아놓은 Utility
// 구조 분해 방식
const { calsLogger, CompareUtility, ConvertUtility, RandomUtility, StringUtility, FsUtility } = require('@cals-framework/lambda')

// 변수 할당 방식
const calsLogger = require('@cals-framework/lambda').calsLogger
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요청 전문에 특정 파라미터가 존재하지 않을 경우 발생하는 에러 클래스
// 구조 분해 할당 방식
const { AlreadyExistException } = require('@cals-framework/lambda')
throw new AlreadyExistException()

// 변수 할당 방식
const DataSQLException = require('@cals-framework/lambda').DataSQLException
throw new DataSQLException()