Q/A에서 답하지 못한것들
최근에 파이콘에서 발표할 기회가 있어, 초짜 파이썬 개발자가 FastAPI로 서비스 만들면서 겪은 좌충우돌 삽질기라는 제목의 세션을 열었습니다. 누가 초짜 아니랄까봐 세션 시간 조절에 실패해서 참석하신 분들의 Q/A에 답을 못해드린 관계로 이렇게나마 답변을 해드리고자 합니다. 글의 내용은 제 개인적인 생각이므로 첨언이나 의견은 매우 환영하며, 경어는 생략하니 양해 바랍니다.
주니어 파이썬 개발자를 넘어 주니어 개발자로 묶어 답을 해보자면,
먼저 개발자로 살아가는 즐거움을 찾아야 한다. 이게 단순히 "개발자로 사니까 즐거워"라는 매우 추상적인 즐거움으로 묶어버린다면 언젠가는 그 즐거움이 "개발자로 살아가는 고통"에 잡아먹힌다. 그걸 막기 위해서는 즐거움의 구성요소를 세분화 해두면 어떠한 경우에라도 "개발자"라는 삶 자체는 유지할수 있지 않을까. 개발자로 살아가는 즐거움의 예를 몇가지 들어본다면, "내가 만든 무언가를 누군가가 쓴다는 것"도 즐거움이 될수 있고 "문제에 막혀 며칠씩 머리를 앓다가 어느순간 깨달음이 오면서 해결한것"도 즐거움이 될수 있다. 열일 제쳐놓고 이걸 찾든 만들든 세뇌를 하든 그거부터 하시라.
그 다음으로 도움이 되면 좋은 속성 몇개 뽑아보자면
호기심. 이 업계는 끊임없이 발전하고 있고, 요 근래들어서는 발전속도가 미쳐버릴듯한 속도가 되어버렸기에 현실적으로 다 따라 잡는건 무리다. 그럼에도 불구하고, 호기심을 품고 세상이 어떻게 돌아가는지는 틈틈히 봐두는게 좋다. 실천방법으로는 이미 다들 하고 있겠지만, 뉴스레터 구독과 커뮤티니 활동을 권장한다.
깊이와 넓이에 방향성을 추가하는것을 권한다. "깊이와 방향을 다 갖춰야 한다"라는 말에 대해 그 필요성은 동의하지만 아쉬운 부분은 둘다 중요하고 필요하다면서 정작 기준점이 없다. 기준점 없이 걍 둘다 필요해라고 말하는 것은 사람수와 모일 장소도 안알려주고 이번 주말에 모여서 밥먹을거니까 식당 예약하라는 소리나 다름없다. 그러므로 깊이와 방향을 만드는데 있어 그 전에 방향성부터 정하는게 우선이지 않을까. 그리고 방향성도 두가지 축이 있다. 하나는 기술축이고 또하나는 도메인 지식이다. 단, 사실상 AI가 많은 부분을 대체하고 있는 지금의 상황을 볼때 저 두 축도 무작정 깊이와 넓이를 확보하는건 시간낭비다. 내 경우이지만 예를 들자면, 일반적인 경우에 한해서(일반적이지 않은 경우의 예: 임베디드 하면 연봉 10억) "B2C 서비스를 제공하는 웹서비스 백엔드 개발자" 라는 기준축을 만들어 놓고 깊이와 넓이를 만들어가고 있다. 그리고 깊이와 넓이가 적당한지 가늠해보는 잣대로는 실용성(최소한 이정도는 갖춰놔야 제대로 된 서비스를 만들수 있다)과 응용성(최소한 이정도는 알고 있어야 다른 분야에서도 적용해 볼수 있다)이라는 기준으로 재어보고 있는 중이다. 단 한가지, 늘 깊이를 추구해야 하는 예외가 있다면 컴퓨터 기초 지식이다. 기초는 알고 있어도 다져라. 틈틈이 다져놔라. 내가 잘 다지고 있는지 확인할수 있는 좋은 방법이 하나 있다면, 관련된 지식이나 개념을 응용해서 개그나 드립을 칠수 있느냐라는 질문을 권장한다.
소프트스킬. 당신이 혼자서 모든것을 만들어 낼수 있는 우주굇수가 아니라면, 어찌됐든 누군가와 협업을 해야 한다. 개발자도 직장인이고, 누군가와 협업을 하는 동료 혹은 고객사 관계자다. 따라서 소프트스킬이 중요하다. 옛날에는 중니어 좀 넘어가면 그때부터 소프트스킬을 이야기했지만 지금은 다르다. 주니어부터 소프트스킬을 염두에 두고 있어야 한다. 다만, 개인적으로 소프트스킬이라고 하면 내가 받는 느낌은 웬지 "사회생활 올인"같은 느낌이 들어서, 차라리 프로 스포츠쪽에서 쓰이고 있는 단어인 "워크에식"이라는 개념을 더 좋아하는 쪽이다.
마지막으로 한마디 더 덧붙이자면 "큰 시야에서 보는 능력을 추구할것". 그것이 해결하기 위한 문제든, 시스템 아키텍처든, 경력이든.
이부분은 내가 경험했던 시대와 지금이 매우 차이나므로 좀더 주의를 기해 읽어 주시길. 내가 경험했던 시대는 한국의 IT 버블시대이기 때문에 그때의 경험을 지금에 그대로 반영하기에는 무리가 있다.
필요한것보다는 필요없는것을 생각하는게 더 빠를거 같다. 특히나 "이게 필요할까?" "이 분야에서 일할수 있을까?"같은 일종의 장벽같은 질문은 일단 맛부터 보고 결정해도 되므로 정말 불필요하다 생각한다(저 위에 호기심을 써놓은게 다 이유가 있다.) 정말로 관심도 안가고 생각도 없는 분야라면 모를까, 그외의 모든 지식은 다 도움이 된다.
심지어, 기술과 별 관련이 없는것조차도 도움이 될때가 종종있다. 인간의 뇌는 우리가 생각하는것보다 더 추상화에 강하다. 한 분야에서 알고 이해한 지식이 추상성을 거쳐 다른 분야를 이해하는데에 도움이 되는 경우가 생각보다 흔하다. 그리고 실제로 그런 현상이 연구현장에서 발생하는것을 일컫는 말이 "학제간 연구"이다. 그러므로 머릿속에 뭐가됐든 개론정도만 넣어두면 경계를 허무는데 많은 도움이 된다. 개론을 넣는 가장 좋은 방법으로 독서를 추천한다. 개발서적만 읽지 말고 교양서도 종종 읽어 두시라.
정확히는 내가 선호하는 구조라기 보다는 내가 이해하기 쉬운 구조라고 표현하는게 맞을듯하다. 그리고 내가 이해하기 쉬운 구조는 지금은 구닥다리 취급받고 있는 MVC 패턴이고, 발표할때 소개했던 프로젝트의 구조도 MVC의 아류에 비슷한 구조라고 할수 있을듯. 다만 프로젝트 구조를 잡을때 이전에 Spring Boot + Kotlin하면서 배운것과 한맺힌것(?)을 풀기위해 노력했는데, DTO계층의 유효함을 배운것을 응용하는것과 의존성 주입이라는 것을 이해하지 못해 한맺힌 것을 풀기위해 노력했다.
이렇게 했으면 더 좋지 않았을까라는 생각이 들었던 지점은 역시 클래스..클래스를 쓰면 합성이나 상속같은 개념을 이용할수 있지만, FastAPI예제들을 봐도 그렇듯이 비즈니스 로직까지 클래스로 묶어버리는게 실질적으로 도움이 되는가라는 질문에 무조건 긍정하기는 어렵다. 만약 이부분을 지금 다시 만든다면, 비즈니스 로직은 전부 함수단위로 빼고 DTO를 클래스로 만들어 여기에서 상속과 합성을 적극적으로 활용하는게 더 좋은 접근이 아니었을까 하는 생각이 든다.
이 질문을 받고 생각해보니, 프로젝트 시작할때 시간에 쫒겨 참고할만한 코드를 많이 보지 못한것 같아 뒤늦게 찾아보게 되었다. 한번 훎어보는것을 권장한다.
참고할만한 사이트https://kludex.github.io/awesome-fastapi-projects/
https://github.com/LAION-AI/Open-Assistant/tree/main
https://github.com/AUTOMATIC1111/stable-diffusion-webui
https://github.com/reworkd/AgentGPT/tree/main
일단 "대규모"의 정의가 외부 기준(ex. 사용자, 트래픽...)인지 내부 기준(ex. 팀 인원수, 서비스에 필요한 기술스택...)인지를 생각해 봐야 하는데, 내가 일했던 회사중 가장 큰 회사(쏘카)를 기준으로 이야기 해보겠다.
일단, 외부 기준에서의 시스템 부하는 스케일 업/아웃으로 극복할수 있는 문제이므로 판단하기가 좀 애매한것 같다. 그래도 순수하게 비즈니스 로직에 대한 서비스만 제공한다고 하면 FastAPI만으로도 충분히 가능할 것이라 생각한다.
다만, 서비스를 운영할 경우 RestAPI만 제공해줘서는 제품이나 서비스의 기능적 요구사항을 충족시키기 어렵다. 특히나 인하우스 툴에 대한 개발 소요를 자체적으로 해결하는 회사의 경우 고민할 일이 많아진다.
회사에 개발팀이 충분히 있어서 F/E를 만드는 조직이 따로 있고, 인하우스 툴을 만드는것도 F/E가 전담한다고 하면 괜찮겠지만 그렇게 여유있게 사람을 운영하는 조직은 많지 않다. 따라서 결론을 내자면, 빠르게 시장에 진입하고 싶다면 FastAPI가 좋겠지만 장기적으로 본다면 Django가 차라리 무난한 선택이라 본다. 물론 MVP를 최단시간안에 FastAPI로 만들어서 시장성을 타진해보고 괜찮다 싶음 Django로 넘어가는 전략도 생각해볼만 하다. 둘 다 익숙하다는 전제가 있어야 하지만.
FastAPI도 jinja2같은거 쓰면 관리자 페이지 뚝딱뚝딱 만들수는 있는데...살짝 시도한 바로는 좀 짜치기는 하더라만.
이와 엮어서 Spring Boot를 많이 써보지는 않았지만 굳이 비교해보자면, 단점...이라기 보다는 차이점이 아닐까 싶은데 SpringBoot는 언어와 프레임워크 자체적으로 제공해주는게 많아서(물론 https://start.spring.io/ 에서 초기에 필요한것들을 담아줘야 하겠지만) 프로젝트 진행해 나가며 추가 패키지를 설치할 일이 그리 많지 않다. 하지만 FastAPI는 기능 구현하다보면 필요한 패키지가 점점 늘어나고, 그때그때 정신차리고 requirements.txt를 갱신하지 않으면 안된다는 귀찮음이 존재한다.
역시 장단점보다 차이점? node js 기반 프레임워크는 언어 특성상 콜백 지옥 벗어나기 쉽지 않은데, 파이썬 기반의 FastAPI는 그럴일은 없어서 좋았다일까. 다만 FastAPI는 굳이 sync / async로 작동을 나눠놓은것이 혼란스러웠다. 그것도 다 이유가 있어서 그렇게 만들었겠지 싶지만, 개인적으로는 하나의 코드 안에 저 두개가 뒤섞이니 종종 실수할때마다 좀 불편하게 느껴졌다.
내가 느끼기에 파이썬의 가장 큰 특징이라면 타입힌트 같은데...약타입 언어인 PHP는 타입힌트가 7.4 버전부터 추가되었고 내가 딱 PHP로 일하는것을 멈춘때가 그때 즈음이다. 그 다음으로 잠깐 접한게 강타입 언어인 Kotlin이었다. Python은 딱 그 중간쯤 위치해 있다는 느낌을 주었는데, 어지간하지 않고서는 타입문제로 들이박지 않는 kotlin보다는 편하고 개발자의 실수를 막아주는 타입힌트가 있어서 편리했다. 그리고 발표에도 이야기했지만 타입 자체도 오브젝트라는 개념을 제대로 이해하지 못해서 그런가 그 부분도 인상깊다. 또 삽질하지 말아야지.
이건 기존 스택이랄게 별로 없는게, 애초에 회사에서 파이썬을 썼기 때문에 그 방침을 그대로 따른것 뿐이다. 물론 다른 언어라는 선택지가 있긴 하지만 회사안에서 제품은, 서비스는 나혼자 만드는게 아니기 때문. 또한 하도 파이썬이 성능 않좋다라는 말이 있기는 해도, 어짜피 도메인 자체가 고객이 수천수백만명 생겨서 수시로 서버가 터져나갈만한 시장 규모는 아니기 때문에 파이썬으로도 충분하다는 생각이 들었다.
실제 실무자들의 소통은 당연히 있었다. 참고로, 나는 내가 만든 물건을 직접 쓰는 사람을 만나는 것을 대단히 좋아한다. 만드는 사람은 만드는 사람 입장에서의 생각에 묶일 수 밖에 없다. 이른바 "공급자 마인드"라는 것인데, 이걸 깨는 방법은 실제로 쓰는 사람 만나서 이야기해보는게 제일이다. 개밥먹기 같은 내가 직접 써보는것도 방법이긴 하지만, 어떻게 해도 개발자는 진정한 도메인 전문가가 될수는 없다. 공장에서 십몇년 이상씩 일한 사람의 컨텍스트를 한번에 따라잡는것은 물리적으로도 불가능한 이야기다.
다만 아쉬운것은, 대부분의 B2B 비즈니스는 늘 이야기가 묘하게 SI처럼 흘러간다는 것이다. 현장 담당자를 만나보면 항상 "우리는 이런게 필요해, 그거 없으면 안써. 비싸니까 깎아줘"라는 이야기가 나오고, 그 이야기는 불특정 다수의 기업 고객을 목표로 하고 있는 이 서비스와 결이 안맞을 가능성이 컸다. 하나의 고객에 맞춰 커스터마이징 한것이 다른곳에서도 통한다는 보장은 없으니까. 생산현장, 공장이라는 곳은 겉보기에는 원자재를 밀어 넣으면 굴뚝에서 연기가 나오고 창고에 출하할 제품이 쌓이는 것이 전부 똑같이 보여도 그 안에는 각자의 니즈와 스토리가 있다. 그것을 잘 파악하지 못한것이 어쩌면 한계가 아니었을까.
이건 답해주고 싶어도 워낙 써보지를 못해서...생략!