2026 개정판 · 1차 8월 8일 공개전체 커리큘럼 →
TECH 으로 돌아가기
TECH HACKER NEWS 오늘 8분 읽기 35 READS

버튼다운이 8년간 장고에서 얻은 것: 보이지 않는 추상화의 힘

버튼다운이 8년간 장고에서 얻은 것: 보이지 않는 추상화의 힘
SOURCE IMAGE · HACKER NEWS

좋은 프레임워크는 시간이 지나면 눈에 띄지 않게 된다. 뉴스레터 서비스 버튼다운(Buttondown)을 운영해 온 개발자는 자사 코드베이스를 아무리 들여다봐도 "이건 장고(Django)다"라고 딱 집어 말할 부분을 찾기 어려웠다고 고백한다. 장고적인 요소가 파이썬다운 코드나 순수한 비즈니스 로직과 워낙 매끄럽게 섞여 있어서다. 그가 보기에 버튼다운은 '장고 앱'이 아니라 '자기보다 똑똑한 사람들이 이미 풀어놓은 문제들 위에 잘 구조화된 코드베이스'다. 역설적이게도 이 투명함, 즉 적당히 의견을 강제하면서도 결국 배경으로 사라지는 성질이야말로 그가 장고를 사랑하는 이유다. 이 글은 그가 지난 몇 년간 가장 큰 레버리지를 얻은 추상화들을 되짚은 것이다.

미들웨어와 베이스 모델이라는 지렛대

그가 첫손에 꼽는 것은 미들웨어다. 장고 미들웨어는 요청/응답 생명주기에 개입하는 단순한 함수이며, 그 프로토콜만 따르면 내부에서 무엇이든 할 수 있다. 버튼다운은 이 훅을 활용해 서브도메인 기준으로 요청을 올바른 뉴스레터로 라우팅하고, UTM·유입 경로 같은 어트리뷰션을 수집하며, Content-Security-Policy 헤더를 설정하고, 페이지뷰를 기록하고, 요청 컨텍스트를 구조화 로그에 결합한다. 심지어 모든 응답에 배포된 깃 SHA를 찍어, 오래된 브라우저 탭이 새 빌드가 나왔음을 알아채도록 한다. 그는 "평균적인 장고 개발자가 더 활용해야 할 도구가 하나 있다면 바로 미들웨어"라고 단언한다.

또 하나의 축은 모델 상속이다. 버튼다운의 모든 모델은 하나의 베이스 모델을 상속한다. 이 베이스 클래스는 조용히 많은 일을 하는데, 핵심은 그 모든 기능이 옵트인 방식이고 부가적이라는 점이다. 공통 기능을 덧붙일 때 별도의 마이그레이션이나 대대적인 리팩터가 필요 없다. 예컨대 새 필드에 대한 변경 이력(provenance) 추적을 붙이려면 모델이 메서드 하나로 옵트인만 하면 되고, 나머지는 베이스 클래스가 처리한다. 장고식 객체지향의 이 '조각별(piecemeal)' 접근이야말로 실무에서 두고두고 편리했던 지점이다.

지루할 만큼 엄격한 뷰와 액션 분리

버튼다운은 모델 클래스가 수십 개의 메서드로 비대해지는 것을 막기 위해, 모델이 겪을 수 있는 각 행위를 모델 옆 actions/ 폴더에 한 파일씩 분리한다. 모듈 하나에 동사 하나, 각각 call()을 노출하는 식이다. '구독자 차단(ban)' 같은 동작이 또 다른 액션을 조합해 구성된다. 뷰에 대한 태도도 마찬가지로 교조적이고 단순하다. 모든 뷰가 지켜야 할 규칙을 강제하는데, 이렇게 지루하고 엄격하게 가는 이유는 컨텍스트 전환의 고통 때문이다. 그의 지론은 유지보수 가능한 뷰 코드란 '성공을 찾는' 것보다 '실패를 피하는' 데 가깝다는 것이다. 실패는 불필요한 간접화와 코드 재사용 부족에서 오며, 뷰를 함수형 관점에서 최대한 '순수'하게 유지하면 둘 다 예방된다.

테스트 역시 실용주의를 택했다. pytest와 pytest-django, 그리고 수많은 플러그인을 쓰지만 Factory Boy 같은 기성 픽스처 생성기는 쓰지 않는다. 성능을 더 짜내기 위해 픽스처를 직접 구성하며, 테스트는 필요한 픽스처를 인자로 받아 실제 DB 행에 대해 검증하는 평범한 함수다. 백엔드 테스트 스위트가 오랫동안 CI 파이프라인의 가장 긴 병목이었던 만큼, 지난 1년간 그의 상당한 시간이 이 파이프라인을 빠르게 만드는 데 투입됐다.

쓰지 않기로 한 것들

루비 온 레일스가 '오마카세'로 유명하다면, 장고에서 그가 사랑하는 부분 중 하나는 오히려 쓰지 않기로 결정한 것들이다. 시그널(signal)은 django-allauth와 연결되는 단 하나만 남겨뒀다. 자신들이 소유한 코드끼리 시그널로 잇는 것은 무슨 일이 벌어지는지 추론하기 어렵게 만들고 나중의 성능 개선을 방해하는 안티패턴이라고 봤기 때문이다. 클래스 기반 뷰도 배제했다. 어떤 상황에서는 장점이 있겠지만, 함수형 뷰와 클래스형 뷰 사이를 오가는 컨텍스트 전환 비용이 그 미미한 이점을 압도한다는 판단이다. 장고가 권장하는 앱(app) 단위 모듈 분리도 대체로 쓰지 않는데, 앱 간 마이그레이션(특히 스쿼싱)이 까다롭고, 관련 모델을 폴더로 묶는 다른 방식 대비 뚜렷한 이점이 없어서다. 예외는 초기에 그렇게 지어버린 코어 API 인프라와, 훗날 서드파티 패키지로 떼어낼 가능성이 있어 경계를 미리 그어두고 싶은 부분 정도다.

장고의 폼(form) 추상화는 전혀 쓰지 않는다. 프런트엔드 구축 방식이 독특하기 때문이다. 인증된 뷰 대부분에서 장고는 얇은 껍데기를 렌더링하고 데이터를 심는 역할만 한다. 거의 모든 페이지를 하나의 뷰가 떠받치는데, 이 뷰는 세션을 해석하고 계정 정보를(일부 경로에서는 관련 리소스의 첫 페이지까지) json_script 태그로 직렬화한 뒤 Vue에 넘긴다. Vue는 로드 시 API 왕복 비용을 치르는 대신 그 페이로드에서 하이드레이션한다. 장고가 뼈대를 그리면 SPA가 나머지를 채우는 구조다.

마지막으로 이 모든 선택의 출발점은 의외로 밋밋하다. 2018년 당시 그가 다니던 회사의 스택이 장고와 Vue였고, 그는 장고 경험자로 채용된 사람이었다. '혁신 토큰(innovation token)을 아낀다'는 그의 오랜 철학, 즉 본업과 사이드 프로젝트를 오가며 프레임워크 전환에 시간을 쓰고 싶지 않다는 판단이 장고를 낙점했다. 흥미롭게도 그는 지난 8년간 Vue를 택한 것은 후회했다고 털어놓으면서도, 장고 선택만큼은 단 한 순간도 후회하지 않았다고 말한다. 한국의 실무자에게도 이 사례는 시사하는 바가 있다. 프레임워크의 가치는 화려한 기능 목록이 아니라, 팀이 스스로 규율을 세우고 불필요한 선택지를 덜어낼 여지를 얼마나 주느냐에서 나온다는 점이다.

SOURCE · HACKER NEWS
원문 전체 보기 → https://buttondown.com/blog/what-i-love-about-django
SHARE
NEXT · CHOOSE

변화를 읽었다면,
내가 만들 수익 구조를 고릅니다.

정보를 더 모으는 데서 멈추지 않고, 광고·외주·판매·중개·구독 중 내 상황에 맞는 출발점을 정해보세요.

21가지 수익 구조 살펴보기
처리 중...