18P by xguru 2달전 | favorite | 댓글 3개
  • 2년전에 모바일/웹/백엔드를 만들기 위해서 선택했던 기술들과 그에 대한 회고를 기록
  • 매우 간단한 일반적인 SaaS 였어서 최소의 노력과 자원으로 빨리 부트스트래핑 하는 것을 목표로 함
    디자인 역량이 제한적이라 모바일앱은 직접 개발하지 않고 외주로 돌리고, 백엔드와 웹만 개발

기술 선택들

모바일 앱

  • 오랜 닷넷개발자였지만 Xamarin 으로 개발 하는걸 원치는 않았음
  • iOS/Android 동시 지원을 위해 Flutter를 선택
  • 몇주만에 양쪽에서 동작하는 앱이 나와서 Time to Market 관점에서는 훌륭
  • UI는 약간 결함이 있긴 했지만, 우리같은 B2B 유스케이스에선 무시할 수 있었음
  • Flutter 자체는 버그&문제가 많았지만, Show-Stopper 수준은 아니었음
  • 언어로서의 Dart는 별로였지만 문제는 아니었음. (어차피 내가 개발 안하니까)
  • Xamarin을 그냥 고수하거나 React Native를 선택하는게 더 나았을 수도

API

  • 스케일이 중요한게 아니었음. 첫 고객들 일부한테만 제공했으면 되니까
  • 그래서 쿠버네티스/서버리스 등은 다 무시하고 그냥 Monolith로 개발
  • 싱글이지만 모듈화된 닷넷 어플리케이션으로, F#으로 코딩하고 Onion 아키텍처(Ports & Adapters 패턴)를 따랐음
  • GraphQL 같은것도 무시하고 그냥 올드한 REST 방식으로
  • 결과
    • API는 매우 튼튼하고 빠름. 배포중 거의 문제가 발생하지 않음
    • 증명할 수는 없지만, 이 성공의 대부분은 내가 사용한 "Applied Functional Programming" 어프로치 때문이라고 생각
    • 또한 F# 코드는 매우 아름답고 읽기 쉽고 이해하기 쉬움
    • 매우 적은 수의 오픈소스 라이브러리에 의존하므로, F# 에코시스템이 상대적으로 작고 느리게 움직인다는 것은 문제가 되지 않음

Persistence

  • SQL Server를 오래 써왔지만 DB에 라이센스 비용을 들이기는 싫었음
  • 그래서 PostgreSQL로 선택하고 싱글 DB서버로 API가 사용. 약간의 큐 메커니즘 포함
  • 제품에 BLOB 저장소가 필요해져서, 그냥 서버의 파일 시스템을 사용하기로 했음
  • 결과
    • 그냥 동작함(It just works). Postgres와 함께하는 것은 즐거움
    • JSONB 데이터 타입은 Relational 과 NoSQL 테크닉을 섞어서 사용 가능하게 해줌. 매우 안정적이고 편안한 방식으로
    • JSON 쿼리 문법을 외울 필요는 없을듯
    • BLOB을 그냥 디스크에 저장하는 것은 큰 결정이지만, AWS S3 같은 것을 사용하는 것은 적은 사용자수에 큰 도움이 되지는 않았을 것

Web App

  • 웹앱에 대한 기술 결정은 꽤 오래걸렸음
  • 내 직감은 Fable 과 F#을 선택하라고 했지만, 결국엔 React 와 TypeScript를 사용하고 SPA를 구축하기로 결정
  • 초기에 한 결정중에 중요한 것은 Tailwind CSS를 채택한 것
  • 결과
    • React just works, TypeScript just works
    • Dart 와 마찬가지로 TypeScript 작성도 별로 좋아하지 않고, 읽는 것도 그닥
    • 다만 TS엔 훌륭한 기능들이 있긴 함. Discriminated unions 같은 기능은 F# 에도 있으면 좋겠음
    • 전반적으로 개발자 경험은 훌륭. 빌드시간이 엄청 짧고(F#에 비해), 대부분의 복잡한 UI문제에 대해서 패키지들이 이미 존재함
    • 함수적 프로그래밍 각도에서 봐도 React의 전체 애플리케이션 모델은 이해 가능
    • Tailwind CSS는 엄청 많은 부하를 줄여줌

Infrastructure

  • Monolith로 가기로 하면서 선택은 쉬워졌음
  • Hetzner에서 리눅스머신을 빌려서, 3개의 도커 컨테이너를 실행 : Postgres , DotNet API, Nginx
  • 모든 것은 GitHub Actions 로 빌드되고 자동 디플로이
  • 결과
    • 클라이언트와 백엔드를 동시에 배포하면 다운타임이 발생하지만, 현재로서는 짧고 무시 가능
    • 전체 프로세스는 슬림하고 안정적이며 비용 구조도 마찬가지. Hetzner는 정말 저렴하다

정리

  • 현재의 결정에 매우 만족
  • 이전 프로젝트보다 더 넓은 규모로 F# 및 함수형 프로그래밍 작업에 투자했음
  • 프로젝트에 F#, TypeScript, Dart 세개의 언어는 좀 많음.
    Dotnet MAUI가 Flutter 만큼 성숙하지 않지만, 자주 사용하지 않는 다른 언어 대신에 선택은 가능할 듯

장기적으로 볼 때 인력 수급이 원할할까요?

저건 아마도 혼자 운영하는 서비스인듯 하네요. 인력보다는 자신이 유지보수하기 편한쪽으로 생각한듯 해요.

저랑 안 맞는 부분들도 조금은 있지만.. 이 사람한테 맞는 나름 실용적인 선택들이었던 것 같아요.