Project structure
1. Folder structure explanation
1.1. A space for defining environment configuration values.
1.2. A folder that gathers constants used within the project.
1.3. A folder for storing class files defining Exception
1.4. A folder for storing class files using external libraries.
1.5. A space for storing class files of model
definition.
1.6. A location for query XML
files.
1.7. A folder for storing business-related source code used in the project.
1.8. A folder for managing common source code used in the project.
2. File structure explanation
2.1. config
/projectBaseConfigDev.js
: is a config file to debug in Local
environment.
"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 {
/**
* Create constant variables with a constructor
*
* @constructor
*/
// Can modify from this part
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";
// A Variables that can control the output range of log
this.Logger.LEVEL = LogLevel.DEBUG;
// A variables can control whether calsLogger.param active or not
this.Logger.ParamEnabled = false;
// A variables can control whether calsLogger.result active or not
this.Logger.ResultEnabled = false;
// A variables control whether query 로깅 active or not
this.Logger.DBLogEnabled = true;
this._DB.ENGINE = "mysql";
// This connection is used for development purpose
this._DB.CONNECTION_TYPE = DB_CONNECTION_TYPE.CONFIG;
// Input host of DB to be used for test. (Generally, local DB uses 127.0.0.1 is used)
this._DB.HOST = "{{dbHost}}";
// Input user name of DB to be used for test. (Generally, local DB uses root.)
this._DB.USER = "{{dbUser}}";
// Input user password of DB to be used for test.
this._DB.PASSWORD = "{{dbPassword}}";
// Input schema of DB to be used for test.
this._DB.SCHEMA = "{{dbSchema}}";
}
}
module.exports.ProjectBaseConfigDev = ProjectBaseConfigDev;
2.2. constant
/projectBaseConstant.js
: is file to organize constants used within project.
'use strict'
/**
* @fileoverview file containing constant variables
*/
/**
* 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 {
/**
* Creating constant variables with constructors
* @constructor
*/
// can modify from this part
constructor () {
super()
}
static ERROR_MESSAGE = {
NO_AFFECTED_QUERY: 'NO AFFECTED QUERY'
}
static QUERY_INFO = {
selectTest1: {
name: 'selectTest1',
type: this.ORM_QUERY_TYPE.SELECT
}
}
}
2.3. lib
/lambdaLib.js
: this file creates a class including an external library to be used within the project.
'use strict'
/**
* @fileoeverview Sample Library module
* lambdaLib.js
*/
const os = require('os')
const { LambdaBaseLib } = require('@cals-framework/lambda')
/**
* Lambda Sample Library module
* @module LambdaLib
* @example
* const RdkLambdaLib = require('./lambdaLib.js)
* const clsRdkLambdaLib = new RdkLambdaLib()
* @desc Lambda Sample Library module
*/
module.exports = class LambdaLib extends LambdaBaseLib {
/**
* Creating Library object by the constructor
* @constructs
* @param
*/
constructor () {
super()
this.homeDir = os.homedir()
this.hostName = os.hostname()
this.getTempDir = getTempDir
}
/**
* getTempDir function
* @function
* @param
* @desc return to temp Directory
*/
getTempDir() {
return this.path.resolve(os.tmpdir())
}
}
2.4. model
/lambdaModel.js
: This file defines a Model
object to be used within the project.
'use strict'
/**
* @fileoeverview Sample for Model module
* lambdaModel.js
*/
const { ApplicationLambdaBaseModel } = require('@cals-framework/lambda')
/**
*Sample for Model module
* @module LambdaModel
* @example
* const LambdaModel = require('./lambdaModel.js')
* const clsLambdaModel = new LambdaModel()
* @desc Sample Model module
*/
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
2.5. src
/controller.js
: This file contains the source code for validating the received event values and setting default values according to the MVC
pattern.
'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 : Check validity of parameter , check session
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
: This file contains the functions that implement the business logic.
'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. Create model to register data
const SampleAddDataModel = require('../model/lambdaModel').SampleAddDataModel
const objSampleAddDataModel = new SampleAddDataModel()
// 2. Register data, register data in model
objSampleAddDataModel.sampleName = objRequestParams.sampleName
objSampleAddDataModel.sampleDesc = objRequestParams.sampleDesc
// 3. Input data
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
}
// can modify up to here
}
/dao.js
: is the file that accesses database and execute SQL
.
'use strict'
const { ApplicationDAO, calsLogger } = require('@cals-framework/lambda')
const ProjectBaseConstant = require('../constant/projectBaseConstant')
module.exports = class DAO extends ApplicationDAO {
// can modify from this part
async addData ({ objDAOParams, objReturn }) {
calsLogger.param(objDAOParams)
const objDAOReturn = await this.insert({
sQueryId: 'insertData',
objParam: objDAOParams,
objReturn
})
calsLogger.result(objDAOReturn)
return objDAOReturn
}
}
2.6. util
/rdkProjectBaseUtil.js
: This file contains a utility source created by the utility in the project.
'use strict'
/**
* @fileoeverview Sample for module Util
* lambda util Base module
*/
const { RdkLambdaBaseUtil } = require('@cals-framework/lambda')
const LambdaLib = require('../lib/lambdaLib')
const clsLambdaLib = new LambdaLib()
/**
* Sample module Util
* @module RdkProjectBaseUtil
* @example
* const RdkProjectBaseUtil = require('./rdkProjectBaseUtil.js')
* const clsRdkProjectBaseUtil = new RdkProjectBaseUtil()
* @desc Sample module Util
*/
/**
* Sample for module Util
* @class
*/
module.exports = class RdkProjectBaseUtil extends RdkLambdaBaseUtil {
constructor () {
super()
this.getOsInfo = getOsInfo
}
}
/**
* Sample function to return OS information
* @function
* @desc function to return OS information
*/
const getOsInfo = () => {
return {
hostName: clsLambdaLib.hostName,
homeDir: clsLambdaLib.homeDir,
tmpDir: clsLambdaLib.getTempDir()
}
}
2.7. app.js
The file that specifies the handler
required to run the Lambda project
.
'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
3. Framework Context
3.1. logger & Utility
Class name | Explanation |
---|---|
calsLogger | Object Logger provided in Lambda Framework |
CompareUtility | Utility that collects frequently used functions for comparing values |
ConvertUtility | Utility that collects frequently used functions for converting values |
RandomUtility | Utility that collects frequently used functions related to random operations, such as returning integers |
StringUtility | Utility that collects frequently used functions for string values |
FsUtility | Utility that collects frequently used functions for file system |
// Destructuring method
const { calsLogger, CompareUtility, ConvertUtility, RandomUtility, StringUtility, FsUtility } = require('@cals-framework/lambda')
// Variables allocation method
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..
// it can be used when developer want to debug log
calsLogger.param(“param log..”)
// => 2024.01.12.T08:46:18.863 [PARAM] - [PROJECT] param log..
// It is used to check parameter
calsLogger.result(“result log..”)
// => 2024.01.12.T08:46:18.863 [RESULT] - [PROJECT] result log..
// It is used to check return value of function
calsLogger.error(“error log..”)
// => 2024.01.12.T08:46:18.863 [ERROR] - [PROJECT] error log..
// It is used when leave 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')
3.2. Exception
Exception name | Explanation |
---|---|
AlreadyExistException | Error class that occurs when data already exists. |
DataSQLException | Error class that occurs when there is a problem executing SQL. |
InvalidRequestException | Error class that occurs when an invalid request is made. |
MultiDataSelectException | Error class that occurs when multiple data is selected unintentionally. |
NoDataException | Error class that occurs when no data is found in the request message or database query results. |
OperationFailException | Error class that causes problems when executing a specific operation. |
ParameterNonExistException | Error class that occurs when no parameter is found in the request message. |
// // Destructuring allocation method
const { AlreadyExistException } = require('@cals-framework/lambda')
throw new AlreadyExistException()
// variables allocation method
const DataSQLException = require('@cals-framework/lambda').DataSQLException
throw new DataSQLException()