Node.js Architecture

영슈·2023년 1월 26일
0

Express js Framework

목록 보기
1/3

원본 :
https://www.softwareontheroad.com/ideal-nodejs-project-structure/

Folder Structure

  1. app.js : Application 진입점
  2. api Folder : Controller 를 모아놓은 Folder
  3. config Folder : Env variable ( 환경변수 ) + configuration
  4. jobs Folder : Linux Cron 들을 모아놓은 Folder ( agenda.js 사용 )
  5. loaders Folder : Module & startup Processing 모아놓은 Folder
  6. models Folder : Database Model 모아놓은 Folder
  7. services Folder : Business Logic 을 모아놓은 Folder
  8. subscribers Folder : Event Handler + Async task 모아놓은 Folder
  9. types Folder : Typescript 용 Type 들을 모아놓은 Folder

3 Layer Architecture

Controller <-> Service Layer <-> Data Access Layer

Business Logic Must be in Service

For SOLID Principle & Clean Code , Split Response Code and Background process
Not include Model Query ( Query include Data Access Layer )
1. split Code in express Router
2. Service Layer doesn't include Req , Res Object
3. Service Layer doesn't include Status Code and Http Header

Dependency Injection

Compatible Dependency , Flexible Code
Unit Test for Service , Another Context can use Code

Before

import UserModel from '../models/user';
import CompanyModel from '../models/company';
import SalaryModel from '../models/salary';  
class UserService {
  constructor(){}
  Sigup(){
    // Caling UserMode, CompanyModel, etc
    ...
  }
}

각 Method 마다 따로따로 사용

After

export default class UserService {
  constructor(userModel, companyModel, salaryModel){
    this.userModel = userModel;
    this.companyModel = companyModel;
    this.salaryModel = salaryModel;
  }
  getMyUser(userId){
    // models available throug 'this'
    const user = this.userModel.findById(userId);
    return user;
  }
}

import UserService from '../services/user';
import UserModel from '../models/user';
import CompanyModel from '../models/company';
const salaryModelMock = {
  calculateNetSalary(){
    return 42;
  }
}
const userServiceInstance = new UserService(userModel, companyModel, salaryModelMock);
const user = await userServiceInstance.getMyUser('12346');

=> typedi Library 사용

typedi

import { Service } from 'typedi';
@Service()
export default class UserService {
  constructor(
    private userModel,
    private companyModel, 
    private salaryModel
  ){}

  getMyUser(userId){
    const user = this.userModel.findById(userId);
    return user;
  }
}

route.post('/', 
  async (req, res, next) => {
    const userDTO = req.body;

    const userServiceInstance = Container.get(UserService) // Service locator

    const { user, company } = userServiceInstance.Signup(userDTO);

    return res.json({ user, company });
  });

Spring의 D.I와 매우 유사 , Container가 담당

0개의 댓글