[mulli] 4. Serverpod의 올바른 사용: Flutter 앱 아키텍처 단순화하기

ds-k.dev·2025년 2월 11일
0

mulli 프로젝트

목록 보기
4/4

지금 환경에서 클린 아키텍쳐가 정답일까?

이번 mulli 프로젝트를 사용하면서, 클린 아키텍쳐를 적용하려고 했다. 즉, 데이터 레이어, 도메인 레이어, 프레젠테이션 레이어를 분리하고, 각각의 책임을 명확히 하려고 했으나, 하지만 Serverpod를 사용하면서 이러한 접근 방식에 대해 다시 생각해보게 되었다. 왜냐하면, serverpod에서 이미 dto, repository 등을 미리 정의해주고 있다고 생각했기 때문이였다. 이걸 별도로 또 정의해서 오류 가능성을 높이는 것보다 이미 정의한 모델과 엔드포인트를 그대로 사용하는게 오히려 유지보수 관점에서 적절하지 않을까 하는 생각이였다.

Serverpod가 제공하는 것들

1. 자동 생성되는 모델

Serverpod는 yaml 파일로 정의한 모델을 기반으로 서버와 클라이언트 코드를 자동으로 생성한다. 예를 들어:

class: Products
table: products

fields:
  userId: int
  title: String
  description: String
  price: double
  brandId: int
  clubType: String
  shaftType: String
  flexType: String
  year: int
  region1: String
  region2: String
  region3: String?
  region4: String?
  salesStatus: String
  lat: double?
  lng: double?
  likesCount: int
  reportsCount: int
  isDeleted: bool
  createdAt: DateTime
  updatedAt: DateTime
  images: List<ProductsImages>?, relation
  likes: List<ProductsLikes>?, relation
  reports: List<ProductsReports>?, relation
  chatRooms: List<ChatRooms>?, relation

이 yaml 파일로부터 Serverpod는 다음과 같은 것들을 자동으로 생성한다:

  • 서버 측 모델 클래스
  • 클라이언트 측 모델 클래스
  • 데이터베이스 테이블 정의
  • 직렬화/역직렬화 로직

2. 관계 설정의 자동화

데이터베이스의 관계도 yaml 파일에서 간단히 정의할 수 있다:

fields:
  images: List<ProductsImages>?, relation
  likes: List<ProductsLikes>?, relation
  reports: List<ProductsReports>?, relation
  chatRooms: List<ChatRooms>?, relation

이렇게 정의된 관계는 자동으로:

  • 데이터베이스 외래 키 설정
  • 관계 테이블 생성
  • Include 쿼리 지원

3. 엔드포인트 자동 생성

서버의 엔드포인트를 정의하면, 클라이언트에서 사용할 수 있는 메서드가 자동으로 생성된다:

class ProductsEndpoint extends Endpoint {
  // 모든 브랜드 조회
  Future<List<Products>> getAllProducts(Session session) async {
    return await Products.db
        .find(session, where: (p) => p.isDeleted.equals(false));
  }

클라이언트에서..

var client = Client('http://$localhost:8080/')
  ..connectivityMonitor = FlutterConnectivityMonitor();

이런식으로 서버와 연결을 짓기 때문에,

final users = await client.users.getAllUsers();

이런식으로 바로 엔드포인트를 호출하고 값을 받아올 수 있다.

왜 아키텍처를 단순화해야 하는가?

  1. 중복 제거

    • Serverpod가 이미 모델과 관계를 완벽하게 정의
    • Repository 패턴을 별도로 구현할 필요가 없음
    • 데이터 변환 로직이 자동으로 처리됨
  2. 타입 안전성

    • 서버와 클라이언트가 동일한 모델을 사용
    • 컴파일 타임에 타입 오류 검출
    • API 응답 타입이 보장됨
  3. 개발 생산성

    • 보일러플레이트 코드 최소화
    • 모델 변경 시 자동 업데이트
    • 서버-클라이언트 동기화 자동화

제안하는 Flutter 앱 구조

lib/
  ├── pages/          
      ├── home/
          ├── home_page.dart          # UI 컴포넌트
          └── home_view_model.dart    # Riverpod ViewModel
  ├── widgets/        # 재사용 가능한 위젯
  ├── providers/      # 글로벌 상태 관리
  └── constants/      # 상수 정의

결론

Serverpod를 사용할 때는 전통적인 클린 아키텍처보다 단순화된 구조가 더 효과적이라고 생각했다.. Serverpod가 제공하는 자동화된 기능들을 최대한 활용하고,
Flutter 앱에서는 UI/UX와 상태 관리에만 집중하기로 결정했다.
무조건적으로 클린 아키텍쳐가 옳은가라는 주제에 대해 생각해볼 수 있었고,
또 나름의 생각과 검색 등을 통해 맘에 드는 변화를 만들 수 있어서 의미가 있었다고 생각한다.
지금은 현재 결정이 맘에 드니 이 아키텍쳐로 개발을 진행해보고 추후 더 깊게 공부해보면 좋겠다.

0개의 댓글

관련 채용 정보