파이선 웹서버 뭐가 좋을까? Django vs Flask

Kang Taehoon
Hibike! Quantum’s blog
6 min readOct 17, 2019

지난주 데모데이를 마쳤던 퀴즈플랫폼 Duckhoogosa🔗 프로젝트는 누구나 쉽게 자신이 좋아하는 분야에 대한 퀴즈를 만들고 풀고 그 결과를 공유할 수 있는 플랫폼이다.

컴포넌트는 레트로한 분위기의 nes.css를 사용했고 레이아웃은 flex로 직접 작성했다. 클라이언트와 서버 양쪽에서 AWS S3에 접근하여 유저들의 업로드를 처리했다. 또 어뷰징을 막고 유저를 구분하기 위한 인증은 OAuth 토큰과 AWS Cognito를 활용했다.

이 프로젝트 설계에서 첨예했던 주제는 API와 AWS 인프라를 컨트롤할 파이선 웹서버의 스택선택이었다. Flask와 Django 둘중에 하난데 뭘 결정해야할지에 대한 정보가 많이 부족했다. 인터넷에 검색하면 막연히 이런 정보는 많이 나온다.

Django는 딱딱하다. Flask는 가볍다.

그런데 아직 경험이 없는 나로서는 이 문장이 도대체 어떤 맥락인지 이해가 안됐다. 나는 먼저 Django를 선택해서 부딪쳐보기로 했고 적응할만한 즈음 Django-rest-framework-mongoengine 에 버그가 있어 뒤집어서 최종적으로 Flask와 pymongo를 사용하기로 했다. 그 과정을 이번 글에서 정리하고자 한다.

데이터베이스 설정

Django는?

Django 를 설치하고 튜토리얼을 따라가다보면 장고의 특징이 드러나기 시작한다. Skeleton 프로젝트를 생성하면 덩달아 따라오는 빽빽한 setting.py가 바로 그것이다. 그리고 데이터베이스 파트는 이렇게 생겼다.

이 부분에 장고에서 지원하는 DB Engine과 접속정보를 기입하면 장고는 로드할 때 여기있는 정보를 기반으로 자체적인 백엔드 로직을 구성하여 돌려준다. 여기서 백엔드로직이라 함은 대표적으로 admin 페이지나 회원가입, 읽고 쓰는 기능이다.

Django는 이런 기능을 내장하고 있고 API 리소스 별로 테스트할 수있는 html-UI도 제공한다. 다만 이것들을 사용하기 위해선 위의 Database 항목을 잘 관리해야한다. 이걸 공백으로 두면 에러가 떠서 서버가 켜지지 않는다. 그리고 이걸 지원하는 않는 모듈을 별도로 쓴다면 더미모듈을 설정해줘야한다.

Python에서 MongoDB를 쓴다고 하면 Djongo, Mongo-engine, django-rest-framework-mongoengine, pymongo 등의 옵션이 있는데 Djongo를 빼면 (적확하게 말하자면 Django가 지정한 방식대로 쓰지 않으면) 이런 어드민기능을 지원하지 않는다. 즉 까다롭게 설정하는대신 덕은 못본다는 것이다. 그래서 Django는 딱딱하다. 자기기능을 다 쓸게 아니라면 사용자를 답답하게 만든다.

Flask는?

setting.py가 없다. 그냥 텅텅비어있다. 위 코드는 pymongo를 사용해서 컬렉션을 준비시킨 모습이다. app.py를 읽을때 명시적으로 디비를 지정해놓고 필요할때 유저가 명시적으로 지정해서 사용한다. 유저가 지정할 수 있기 때문에 어디서 무엇이 이루어지는지 확실하게 알 수 있다. 그 대신 Flask가 임의로 만들어주는 로직은 없다고 봐도된다.

서버 플로우

Django는?

Django created the skeleton project 을 실행했을 때 생성되는 서버사이드 MVC(MTC) 모델인데 이미 쓰여진 파일명대로 따라서 Django가 읽어서 플로우를 진행한다.
urls.py → views.py ←template.html 의 구조로 진행한다.
- urls.py : 어떤 view 로 보낼지 결정 (라우팅)
- views.py : 최종 Return ( 컨트롤러)
- template : html 문서 껍데기

views.py

이 코드를 이해하기 위해선 index 함수가 urls.py에서 등록되어 있기 때문에 라우팅 흐름을 타고 작동하는 관계를 알아야한다.

Flask는?

플라스크를 어떤 기능을 어떤 파일명에서 어떤 이름으로 구현하라는 약속이 없다. 필요에 따라 구현하고 구현한 만큼 기능한다. 플라스크는 @view_decorator 로 처리하는 로직이 많다. 덕분에 명시적인 성향이 강해서 한눈에 어떤 로직이 관계되는지 파악할 수 있다. 위는 app 객체에 route를 등록하고 바로 아래에 Response를 반환하는 예제다.

미들웨어

Django는?

setting.py 에서 미들웨어를 등록해놓으면 request할때는 위에서부터 밑으로 적용시키고 response 할때는 아래부터 밑으로 적용해나간다.

https://oz123.github.io/advanced-python/book/middlewares.html

다음은 Django에서 미들웨어를 구현한 모습이다. 위에 있는

MIDDLEWARE = [… my_middleware_directory.MyCheckTokenClass]

의 연장으로 보면 이해하기 쉽다.

어떤 요청에 대해서 이 미들웨어를 적용 할지에 대해서는 객체를 직접검사하고 리턴을 돌려주는 방식으로 구현된다.

Flask는?

이것 말고도 다양한 방법이 지원되지만 세가지를 예로 들었다. 1) app에 등록을 하는 방법 2) decorator를 통해 미리 명시적으로 보여주는 방법. 이때 @app.route 가 상단에 있어야한다. Flask의 방법은 Node — express 와 비슷하다는걸 알 수 있다.

정리

이렇게 보면 Flask는 decorator로 상당히 많은것을 하는것처럼 보이지만 flask_restful을 활용하면 Django처럼 별도의 장소에서 라우팅을 정리하고 적용할 함수형 리소스, 클래스형 리소스을 지정하여서 코드를 깔끔하게 관리할 수도 있다.

flask_restful 기반 API

내가 경험한것을 요약하면 두 프레임워크의 선택기준은 다음과 같다.

--

--

Kang Taehoon
Hibike! Quantum’s blog

HibikeQuantum. 백엔드 개발자였다가 지금은 데브옵스. 장인의 삶을 희망. 엔지니어링이든 사업이든 사물의 가치를 알아보는 멋진 사람이 되고 싶어요.