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

Controller <-> Service Layer <-> Data Access Layer
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
Compatible Dependency , Flexible Code
Unit Test for Service , Another Context can use Code
import UserModel from '../models/user';
import CompanyModel from '../models/company';
import SalaryModel from '../models/salary';  
class UserService {
  constructor(){}
  Sigup(){
    // Caling UserMode, CompanyModel, etc
    ...
  }
}각 Method 마다 따로따로 사용
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 사용
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가 담당