1. API Architecture

요약

  • 코드의 아키텍처(architecture) : 코드의 구조를 더 체계적으로 그리고 효율적으로 구현하는 것.
  • 아키텍쳐 적용의 중요성 : 확장성, 재사용성, 유지 보수 가능성, 가독성, 테스트 가능성
  • 관심사 분리 : 각 코드의 역할을 독립적으로 분리할 필요가 있다.
  1. 코드 구조의 중요성
    확장성, 재사용성, 유지보수 가능성, 가독성, 테스트 가능성

  2. 관심사 분리, Separation Of Concerns
    주된 역할과 집중해야할 기능을 분리하여 서로 다른 기능을 하는 파일은 신경을 쓰지 않도록 하는 것
    역할에 대한 분리

(ex) 회원가입 시 서버의 역할 분리 전/후

파일1파일2파일3
요약Client의 요청 처리서비스 규칙 관련 일만 처리데이터베이스 통신만 처리
1Request body 에서 데이터를 꺼낸다.비밀번호의 길이는 8자리 이상으로 규정한다.데이터를 INSERT INTO로 저장한다.
2JSON Response로 제품 정보를 전달한다.이미 가입한 이메일로는 중복으로 가입할 수 없도록 한다.SELECT로 데이터를 가져온다.
3비밀번호는 암호화해서 저장한다.

2. Layered Pattern

2-1. layer의 구분

  1. Presentation Layer
  • 시스템 사용자/클라이언트 시스템과 직접적 연결되는 부분
  • 백엔드 API에서의 엔드포인트를 정의, 전송된 HTTP 요청(request)들을 읽어 들이는 로직만 구현.
  • 실제 시스템이 구현하는 비즈니스 로직은 다음 레이어(layer)로 넘긴다.
  1. Business Layer
  • 비즈니스 로직을 구현하는 부분.
  • 실제 시스템이 구현해야 하는 로직을 구현.
    ex) 회원가입 엔드포인트 - 비밀번호 8자 미만이면 회원가입 거부 로직
  1. Persistence Layer
  • 데이터베이스 관련 로직: 데이터의 저장, 수정, 읽어 들이기
  • Business Layer에서 필요한 데이터 생성, 수정, 읽기 등을 처리

2-2. Layered 아키텍처의 핵심 요소

단방향 의존성
각각의 레이어는 오직 자기보다 하위의 레이어에만 의존한다.

  • Presentation LayerBusiness Layer에게 의존하고, Business LayerPersistence Layer에게만 의존하게 됩니다. Presentation Layer에서 Business Layer를 건너뛰고 Persistence Layer에 접근하는 일은 절대 일어나지 않습니다.
  • Business LayerPresentation Layer에 대해 완전히 독립적이며, Persistence LayerBusiness LayerPresentation Layer에 대해 완전히 독립적입니다.

관심사 분리(Seperation Of Concern, SOC)
각 레이어 별 역할이 구분되어 명확하다. 역할의 중첩이 없음.

  • Presentation Layer: 비즈니스 로직이 없음
  • Business Layer: 데이터베이스 로직이 없음. 데이터베이스 처리를 하기 위해 Persistence Layer의 코드를 호출해서 사용해야 한다.

장점

  • 확장성 : 각 레이어가 서로 독립적이고 역할이 분명하므로 서로에게 끼치는 영향을 최소화하면서 확장하거나 수정할 수 있다.
  • 가독성 : 레이어가 완벽하게 분리되어 있고 역할이 명확하므로 가독성이 높아진다. 코드 구조를 파악하기 쉽고 각 레이어의 코드의 목적이 명확하고 범위도 확실하기 때문이다.
  • 재사용성 : 레이어가 독립적이므로 business layer는 여러 다른 presentation layer에 적용될 수 있습니다. Express 기반의 API 엔드포인트에 적용된 business layer가 다른 프레임워크를 사용한 엔드포인트에 사용될 수도 있다.
  • 테스트 가능성 : 이미 명확한 역할에 이해 나뉘어 있으므로 각 레이어를 테스트하는 코드도 레이어가 나뉘는 것처럼 명확하게 나눌 수 있으며, 복잡한 로직이 아니라 명확하고 범위가 확실한 기능만을 테스트하기 쉽다. 또한 레이어들 자체가 다른 레이어에서 사용하는 구조이므로 테스트에서 호출해서 테스트해보기가 쉽다.

3. Layered 아키텍처 적용하기

3-1. 역할에 따른 폴더 및 파일 생성

app.js 파일에 속한 signUp 함수의 기능을 역할에 따라 나누어 서로 다른 모듈에서 진행하도록 분리한다

westagram
├── node_modules
├── package.json
├── routes
│   ├── index.js
│   └── userRoute.js
├── services
│   └── userService.js
├── controllers
│   └── userController.js
├── models
│   └── userDao.js
└── app.js

3-2. 역할에 따른 코드 분리

signUp() 함수 👉 controller, service, model 모듈로 분리하기

3-2-1. App: 앱의 초기화

3-2-2. Routes: endpoint 경로 라우팅

  • Router 파일: 외부에서 들어오는 요청을 가장 먼저 맞이하여 하위 폴더로 안내하는 길잡이 역할.
  • index.js: 향후 확장성을 고려하여 생성될 수 있는 다양한 Router(예시: userRouter, productRouter 등)들을 한 곳에 모아 관리하는 역할

3-2-3. Controller (Presentation Layer)

  • API의 엔드포인트들을 정의하고 전송된 HTTP 요청(request)들을 읽어 들이는 로직을 구현.
  • 비즈니스 로직으로 흘러들어가야할 데이터들이 올바른 형태를 띄고 있는지 선검증
  • ex) 서버에서 원하는 특정 데이터의 ‘Key’ 값이 요청시 전해지지 않았을 때 발생하는 Key Error 를 사전에 에러처리로 검열:

3-2-4. Service

  • 실제 비즈니스 규칙(Rule)과 로직(Logic)들이 접목되는 Service 레이어의 코드
  • 어플리케이션을 직접 다루는 운영자 입장에서 기획한 비즈니스 모델들이 접목 되어야 한다.
  • ex) 비밀번호의 조합의 특정 형태규칙:

3-2-5. Models

  • 실질적으로 데이터베이스와 소통하는 레이어
  • ex) typeorm을 이용하여 db에 연결한 후, 앞선 레이어들을 모두 무사히 통과한 데이터들을 db에 직접 Insert 하기.

3-3 Layer dependency(의존성) 순서

  • App → Router → Controller → Service → Models 순으로 갈수록 데이터베이스의 접근에 가까워진다.
  • 각각의 파일에서 export 한 module들을 어느 파일들이 require하고 있는지 그 연결흐름: 상위 레이어에서 오직 하위 레이어로만 의존!

실제 Express를 이용한 서버 웹 개발시 Layered Pattern을 이루는 기본 구조입니다.

  • app.js | server.js: Express App 으로 서버를 여는 로직.
    Express App 인스턴스를 만들고, 필요한 미들웨어를 붙이는 로직.
    • 개발자의 의도에 따라 app.js | server.js 에 각기 다른 기능을 유도하여 두가지 파일 모두를 유지하거나, 두 기능을 한데 모아서 한 파일만을 유지한다.
  • routes: 라우팅(엔드 포인트 나누기) 로직.
  • controllers: 엔드포인트에 해당하는 함수 로직
    • http 요청에 따른 에러 핸들링, service 로직에서 데이터를 받아와서 응답으로 내보내는 로직.
  • services: controller 에서 넘겨받은 인자로 다양한 알고리즘(필터, 정렬 등..)을 처리해 데이터에 접근하는 로직.
  • models: 데이터베이스에 접근하기 위한 모델(DAO)이 정의된 폴더.
    아래 모듈은 의존성 없이 다양한 레이어에서 사용될 수 있지만 반복되는 로직이기에 분리해 놓은 폴더;
    • middlewares: 컨트롤러에 닿기 전에 반복되는 로직을 모듈화 해 놓는 폴더. (ex. validateToken - 인증 / 인가)
    • utils: 의존성 없이 모든 레이어에서 공통적으로 자주 사용되는 로직을 모듈화 해 놓는 폴더 (ex. errorGenerator)
    • .env: 프로젝트 내에서 사용할 환경 변수를 선언해 놓는 곳.
      샘플 양식은 .env.sample에 따로 기입하여 공유한다.
    • node_modules: 노드 패키지 모듈.
    • .gitignore: .env,node_modules를 깃이 관리하지 않도록 함
    • package.json: 노드 모듈을 관리하는 파일

4. 그룹 QnA 기록_11.11

컨트롤러와 서비스 폴더의 차이는 무엇인가?

  • 컨트롤러: 데이터베이스 접근 x, 요청 응답 입출력의 문
  • 서비스: 데이터베이스 접근o, 비즈니스 로직을 담당

코드 아키텍처란?
monolithic architecture vs micro service
app.js 는 동네슈퍼의 개념

코드 관리가 최우선?

  • 코드의 재사용성->
    ex) 마켓컬리에서 컬리뷰티로 분리됐듯이 로그인이나 상품 구매 등 api의 재사용성

트래픽 관리도 해당 아키텍처로 승부할 수 있는가?

코드 구조가 중요한 이유? 왜 세분화된 코드 구조를 가져야 하는가? 어떤 이점이 있는가?

  • 확장성
  • 재사용성, 유지보수 가능성, 가독성, 테스트 가능성

불필요한 임포트가 코드 성능 저하에 영향을 미칠까?
👉 모듈의 크기가 너무 크면 영향이 있을 순 있으나 서비스나 서버에 별다른 영향을 미치지 않아

가독성을 저하시키는 원인?
👉 불필요한 코드(주석), 불필요한 if...else(<->try...catch...throw err), 네이밍 컨벤션,

관심사 분리란?
👉 컨트롤러: 데이터의 입출력, 데이터의 있는지 없는지 확인, 맞는 걸 보내주는
서비스: 기업의 비즈니스 로직
모델: 데이터베이스 접근할 수 있는 객체들이 담긴 레이아웃

각각의 레이어의 역할에 대해 이해하고 있는가?

토큰 발행을 위해 jwt모듈을 사용 해시
해시된 보안관련 개발자의 방향

라우트를 폴더로 해놨는데 왜 폴더 내 js파일로 들어갈 수 있는가?
👉 그 index.js를 기본으로 세팅해놔서

profile
검색하고 기록하며 학습하는 백엔드 개발자

0개의 댓글