본문 바로가기

개발 노트/Experience

[품앗이] FastAPI에 적용했던 두 가지 포인트

728x90
반응형

FastAPI에서 Controller를 Class로 만들어버리기

FastAPI는 CBV(Class-Based View)를 공식적으로 제공하지 않는다. 따라서 기본적으로 함수 기반으로 Controller를 작성하게 되며, 이 과정에서 “관련된 요청들을 어떤 기준으로 묶어야 할까?”라는 고민을 하게 된다.

 

FastAPI-Utils 라이브러리를 활용하면 CBV 구성은 가능하다. 하지만 단순히 CBV를 위해 여러 기능이 포함된 외부 라이브러리를 도입하는 것이 적절한지 의문이 들었다.

 

그래서 라이브러리 없이 해결할 수 있는 방법을 탐색했다.


그 결과, Controller 함수에 @staticmethod 데코레이터를 적용하면 Class로 묶을 수 있다는 점을 확인했다.

 

예시는 다음과 같다.

class AccountMentorReadController:
    router = APIRouter(tags=[f"{TAG} - SEARCH"], prefix=PREFIX_V2)

    @staticmethod
    @router.get()
    def get_mentors(): ...

    @staticmethod
    @router.get()
    def get_mentor(): ...

 

 

Service 계층의 의존성 주입 구성하기

dependency_injector를 활용해 DI(Dependency Injection)를 적용하는 과정이 꽤 흥미로웠다. 특히 Service 계층에 집중적으로 적용했다.

 

이렇게 구성한 이유는 크게 두 가지다.

  1. Repository의 읽기/쓰기 책임을 분리한 클래스를 사용하고자 했고,
  2. 의존성을 dependency_injector로 관리하여 상위 계층에서는 이미 의존성이 주입된 Service만 가져다 사용할 수 있게 만들기 위함이다.

 

예시는 다음과 같다.

class CapabilityService:

    def __init__(self,
                 capability_reader,
                 capability_writer):
        self.capability_reader: ICapabilityReader = capability_reader
        self.capability_writer: ICapabilityWriter = capability_writer

dependency_injector 설정

class CapabilityContainer(containers.DeclarativeContainer):
    from src.application.domain.capability.capability_service import CapabilityService
    from src.application.infrastructure.capability_repository import (
        CapabilityReaderImpl, CapabilityWriterImpl)

    service = providers.Singleton(
        CapabilityService,
        capability_reader=CapabilityReaderImpl(),
        capability_writer=CapabilityWriterImpl()
    )
상위 계층에서 사용
class _CompanyUseCase(metaclass=ABCMeta):

    capability_service: CapabilityService = Provide[CapabilityContainer.service]

 

 

적용해보니 역할이 명확하게 구분되어 구조적인 장점이 있었다. 반면 혼자 진행하는 프로젝트에서는 코드를 지나치게 많이 생성하게 된다는 단점도 있었다.

 

간단한 서비스라면 이 정도 수준의 DI가 필요한가에 대한 고민도 남는다.

 

사이드 프로젝트이기에 학습 목적에서는 충분히 의미 있는 시도였다.

 

실제 서비스 개발에서는 어느 정도 규모에서 DI를 적용하는 것이 적절할지 앞으로 더 고민해볼 예정이다.

 

728x90
반응형