Django개발자의 FastAPI 사용 후기

maintain·2021년 6월 14일
6
post-thumbnail

시작하기 전에

  • Django 개발자라고 쓰긴 했지만 고수는 못 됩니다.
  • 이 글은 FastAPI 사용법을 목적으로 하는 글이 아닙니다. 공식 문서가 매우 잘 작성되어 있으니 공식 문서를 참조하면 좋을 것 같습니다.
  • 이 글에서는 성능적인 부분은 단순 비교가 어려운 부분이 있어 언급하지 않습니다. 간단히 언급하자면 비동기 I/O 기반으로 작동하기 때문에 기존의 wsgi 프레임워크보다 빠릅니다. 공식 문서에서는 Node.js와 Go에 필적한다고 나와 있습니다.

FastAPI는?

StarlettePydantic에 강결합된 python 마이크로 웹 프레임워크입니다. flask와 유사하며 asyncio와 type hint를 적극 활용하는 최신(1.0.0 릴리즈가 되지 않았습니다.) 프레임워크입니다.

장점

1. 파라미터 기반 API 입력 설계

개인적으로는 가장 특징적이고 강력한 부분이라고 생각합니다. inspect 모듈 기반으로 데코레이트된 함수의 파라미터를 해석하여 파라미터 선언부에서 해당 엔드포인트에서 사용할 모든 데이터를 정의할 수 있습니다. FastAPI에서는 다음처럼 API 엔드포인트를 선언할 수 있습니다.

@app.get(
   '/{id}',
    response_model=PostModel
)
async def endpoint(
    id: int,
    page_size: int = Query(...),
    user_agent: str = Header(None),
):
    ~~~

id는 URI의 "{id}" 자리에서 받아서 가져오고, page_size는 쿼리 파라미터로 가져옵니다. user_agent는 user_agent 헤더에서 가져옵니다. Form, File, Cookie 등등 모든 종류의 입력을 이런 방식으로 선언하고 FastAPI가 그걸 해석해서 함수 실행 시에 요청에서 알아서 변환해 넣어주는 것이 가능합니다. 타입 힌트에 따른 유효성 검사는 덤입니다. Django에서는 별개의 처리 클래스를 선언하거나(django-filters, DRF Serializer)를 함수 혹은 메서드 내에서 일일이 가져와야 해서 함수 코드가 다소 난잡해지는 불편이 있었는데, 이 부분이 파라미터로 이동하면서 소스가 간결해지는 점이 굉장히 좋았습니다. 거기에 IDE의 지원을 받아 파라미터는 색이 다르게 표현되니 코드가 더(?) 예뻐지는 장점도 있습니다.

2. Dependency 시스템

FastAPI는 위에서 언급한 Header, Query 등 말고도 특수한 파라미터 Depends가 하나 더 있는데 이게 바로 Dependency입니다. 데코레이터 없이 API 엔드포인트처럼 함수를 선언해서 쓸 수 있습니다.

def get_session(user: str = Cookie(...)):
    with session.begin() as db:
        yield db

이렇게 선언한 함수를 엔드포인트에서 이렇게 쓰면 됩니다.

@app.get('/{id}')
async def endpoint(
    id: int,
    session: Session = Depends(get_session),
):
    ~~~

이 Dependency 시스템으로 FastAPI는 DI 패턴을 강력히 준수하고 있습니다. Dependency에서 다른 Dependency를 사용할 수 있고, 이 관계는 FastAPI가 알아서 해석해줍니다. 의존성 트리에서 같은 디펜던시를 여러 번 사용해도 FastAPI가 알아서 한 번만 실행하고 호출 가능한 객체면 무엇이든 가능합니다. 제너레이터의 경우 pytest의 fixture와 유사하게 엔드포인트 처리 및 에러 핸들링 후 yield 다음 부분이 실행됩니다. 코드 재사용이 굉장히 용이하고, Dependency에서 다른 Dependency를 사용할 수 있는 덕분에 추가 또한 용이합니다. 1에서도 비슷하게 언급한 부분입니다만, 기존에 이런 목적을 위해 쓰이던 유사한 방법 중 하나가 데코레이터 패턴인데, 데코레이터가 파라미터 객체를 수정하는 것과 비교했을 때 파라미터로 어떤 처리를 했는지를 간단하게나마 드러낼 수 있는 점이 코드 가독성에 크게 도움을 주는 것 같습니다.

3. API 문서 생성

1에서 다양한 종류의 입력을 파라미터로 선언했습니다. FastAPI는 여기서 해석한 파라미터로 API 문서를 자동으로 만들어줍니다. Dependency에 선언된 것도 포함되며 Swagger와 ReDoc 스타일이 가능합니다. 주석, 타입 힌트, 함수 이름 등이 명세에 포함됩니다. 자세하게 작성하기 위해선 추가적으로 작성할 것들이 있고, 너무 흔해서 특색 없는 API 문서라는 것이 아쉽지만, 주석이나 타입 힌트가 가독성 및 안정성을 위해 어차피 작성하는 것이 권장되는 것임을 생각하면 굉장한 이점입니다.

그 외..

강결합된 라이브러리인 pydantic이 validation과 type hint 기반의 스키마 작성 역할을 합니다. 기존에 많이 쓰이던 attrs나 3.7에 추가된 dataclass와 비교했을 때 굉장히 간결하게 작성할 수 있다는 점이 큰 이점입니다. 사실 이 부분은 3번에 넣을까 고민한 부분입니다만 문서가 굉장히 자세합니다. 아직까지 크게 레퍼런스의 부족에서 불편을 느끼지 못했습니다.

단점

1. 부족한 서드파티

Django가 풀스택 프레임워크라는 것과 그 역사를 어느 정도 감안하더라도 Django의 서드파티 라이브러리 양은 압도적입니다. Redis, Celery, pytest 등 거의 대부분의 유지보수되는 라이브러리는 Django 서드 파티가 있다고 봐도 무방합니다. 이런 서드파티에서 해주던 부분을 직접 작성해야 하는 것이 조금 불편한 감이 있습니다.
python 관련 라이브러리가 모인 Jazzband Organization에는 Django 서드파티만 2페이지가 있습니다.

2. 부족한 레퍼런스 및 디버깅의 어려움

StackOverflow 질문이나, 다른 사람들의 작성 예시가 부족합니다. 아직 1.0.0버전도 출시가 되지 않은 것을 감안하면 어쩔 수 없는 부분입니다. 거기에 더해 Django 디버그 모드의 트레이스백 표시의 편리함이 쓸 땐 그렇게 유용하게 썼던 것 같지 않은데 막상 없고 보니 아쉽더군요.

3. 디렉토리 구성

Django 같은 경우는 프레임워크 단에서 디렉토리 구조를 강제합니다. 그래서 디렉토리 구조를 결정하는 것을 고민할 필요가 없습니다. 파일이 많아지면 파일을 분리하고 하위 디렉토리 안에 넣으면 그만입니다. 공식 문서에 디렉토리 구조에 관한 부분이 포함되어 있습니다만, 아무래도 Django가 강제하는 것보다 고민할 게 많은 건 사실입니다.

결론

다소 빈약한 단점 부분(...)에서 볼 수 있듯이 FastAPI가 장점이 굉장히 크다고 생각합니다. CI, 테스트 등을 제외한 API 작성 자체는 Github star 변화 보여주듯 Django + DRF보다 몇 걸음 앞에 있다고 생각합니다. 개인적으로는 Django4에서 어떻게 변하는지에 따라 다르겠지만, FastAPI를 추후 프로젝트에서 우선 선택할 것 같습니다.

참조

0개의 댓글