Skip to content

의존성 주입으로 DB를 바꿔보자

n-ryu edited this page Dec 10, 2022 · 10 revisions

지난 이야기

OaO의 근본은 Todo 앱! 이를 위해서 Todo 데이터를 관리하는 시스템을 개발해야 했는데, 현재까지의 상황은 아래와 같았다!

  • 어떤 DB를 써야할지 정해지지 않은 상황

    • 멘토님의 조언에 따라 일단 FE에 집중하여 구현을 진행하기로 했다.
    • FE에 집중하여 구현을 진행하기 위해, 우선 데이터는 로컬에 저장하는 방향으로 진행하기로 했다.
    • 일단 로컬에 저장하는 것일 뿐, 언제든 서버 DB와의 연동이 가능하게끔 계획 중이다! 또, 서비스 특성상 팀원들 중 아무도 사용해보지 않은 graphDB를 도입해야 할 수도 있다!
  • Todo 데이터 관리 시스템 인터페이스를 먼저 정의함

    • 팀원 모두가 FE 개발에 집중하고, 2명은 컴포넌트 구현에, 2명은 Todo 데이터 관리 시스템 구현에 투입되었다.
    • 원활한 병렬작업을 위해서 Todo 데이터 관리시스템(TodoList API)의 인터페이스를 먼저 확실하게 정의하고 구현을 시작해서 컴포넌트 팀이 TodoList API의 내부 로직 구현 정도에 독립적으로 구현을 진행할 수 있게끔 했다!
    • DB를 어디에 구축하든, DB와의 상호작용은 비동기적으로 하는 것이 더 유연한 구현을 가능하게 할 것이라 판단해서 모든 데이터 관리 로직(CRUD 로직)을 비동기 인터페이스로 미리 정의했다.
  • 일단은 메모리를 사용하도록 TodoList API 구현체 개발

    • API 정의가 되어 있으니, 내부 구조는 어떻게 되든 상관이 없다고 판단했다!
    • 알고리즘이 복잡하고, 순수성 등 고려할 점이 많다고 생각해서 일단 별도의 DB 연결 없이 메모리에서 모든 로직이 돌아가게끔 TodoList API의 구현체를 개발했다.
    • 구현 후, 메모리에서 동작하는 로직만으로 컴포넌트 팀의 설계와 잘 융합되어 동작하는 것을 확인했다.

TodoList API에서 DB를 분리해보자

일단 메모리를 사용하는 TodoList API는 온전하게 잘 동작하는 것을 확인했으니, 이제 실제 확장, 아니 적어도 확장성을 고려한 형태로 구조를 변경해야할 차례가 왔다.

현재의 구조는 모든 데이터 관리가 TodoList 클래스에서 일어나는데, 일반적으로 DB가 수행하는 업무만을 별도의 인터페이스로 정의하고 분리해서,나중에 DB의 종류를 바꾸거나 서로 다른 DB를 사용하고 싶을 때 의존성 주입 형태로 DB를 바꾸어가며 사용할 수 있도록 구현하기로 했다!

구조 변경에 앞서서, 아래 그림과 같이 여러가지 구조를 고민해 보았다.

image

  1. 현재구조 : 구현된 TodoList API는 메모리를 이용하는 클래스 인스턴스 형태이다. React 컴포넌트는 이를 전역 상태 형태로 보관하고 필요한 정보가 있거나, 변경 사항이 생기면 TodoList의 메서드를 호출한다. 변경 요청 메서드들은 대부분 변경된 이후의 새 TodoList를 반환한다.

  2. DB를 아예 분리하고, 데이터는 필요할때마다 fetching 함수로 가져온다면 : 가장 일반적인 백엔드-프론트엔드의 관계인 것 같다. 하지만 복잡한 연결관계를 가지고 있는 우리 서비스 특성상, 모든 데이터 관련 로직이 DB를 통해 직접 이루어진다면 느리고 불편하리라는 생각이 들었다. 또, 이미 만들어 놓은 API 구조가 클래스 구조를 따르고 있으므로, fetching 함수 형태로 구현한다면 API 구조를 다 변경해야 해서 미리 인터페이스를 설계해서 얻었던 이득이 없어지리라는 생각이 들었다.

  3. TodoList와 DB만 분리한다면 : TodoList에서 DB에 의존하는 부분만 분리하여 사용하는 방법. 지금까지의 TodoList API의 구조를 바꾸지 않아 호환성을 지키면서도, DB 인터페이스를 별도로 설계하고 이를 TodoList에 주입해서 사용하도록 한다. DB인터페이스는 기초적인 CRUD만 담당하고, 추가되거나 복잡한 비즈니스 로직을 요구하는 부분은 TodoList가 전담하므로, 관심사의 분리도 잘 이루어질 것이다!

  4. Read는 TodoList에서 직접, CUD만 DB로 향하게 한다면 : 2번 방식에서 데이터 조회도 항상 DB에서 직접한다면 비효율적일 것이라는 생각이 들었다. 따라서 Read 계열의 요청들은 모두 TodoList의 메모리에서 바로 꺼내서 주고, CUD만 DB로 향한 뒤, DB에서 CUD 성공 응답이 오면 바로 TodoList와의 싱크로를 맞춰주는 방식으로 구현하면 좋으리라는 판단이 들었다.

네 가지 큰 그림중에서, 다른 팀원과의 병렬 작업을 해치지 않으면서도, 성능도 고려할 수 있는 4번으로 골라 구현하게 되었다!

DB 인터페이스를 먼저 정의해보자

메모리를 사용하던 구조를 DB 인터페이스의 구현체 형태로 분리해보자

Indexed DB를 사용하는 구현체를 추가로 구현해보자

남아있는 숙제

💊 비타500

📌 프로젝트

🐾 개발 일지

🥑 그룹활동

🌴 멘토링
🥕 데일리 스크럼
🍒 데일리 개인 회고
🐥 주간 회고
👯 발표 자료

Clone this wiki locally