// APP FACTORY · EP. 03
비용을 줄이기 위해 자체 서버를 두지 않았습니다. 단순한 비용 절감으로 시작한 결정이 데이터 저장 방식과 외부 API 사용법, 만들 앱을 고르는 기준까지 바꿨습니다.
1. 처음에는 비용을 아끼려는 선택이었습니다
앱 공장에서는 자체 서버를 운영하지 않습니다. 처음에는 매달 나가는 서버 비용을 줄이려는 단순한 선택이었습니다. 앱이 많아질수록 사용자가 거의 없는 앱을 위해서도 서버를 계속 관리해야 한다는 점이 부담스러웠습니다.
그런데 서버를 없애고 나니 비용만 줄어든 것이 아니었습니다. 로그인과 동기화, 운영 장애, 개인정보 보관처럼 서버가 있을 때 따라오는 선택들을 이 공장의 당시 제품 범위에서 제외했습니다. 대신 만들 수 있는 앱의 범위도 분명하게 줄었습니다.
결과적으로 이 제약이 앱 공장의 주제 선정과 코드 구조를 정하는 기준이 되었습니다.
2. 백엔드가 없다는 말의 정확한 의미

여기서 백엔드가 없다는 것은 네트워크를 전혀 사용하지 않는다는 뜻이 아닙니다. 공공데이터 API나 외부 공개 API는 필요하면 사용합니다.
사용하지 않는 것은 제가 직접 운영해야 하는 서버입니다. 사용자 계정을 저장하고, 자체 데이터베이스를 관리하고, 요청량이 늘 때 서버를 확장해야 하는 구조는 만들지 않습니다.
Firebase Analytics와 Crashlytics, Remote Config처럼 무료 범위에서 운영 부담 없이 사용할 수 있는 관리형 기능은 예외로 두었습니다. 서버가 있느냐보다 제가 계속 운영해야 하는가를 기준으로 판단했습니다.
3. 기본 데이터는 기기 안에 저장합니다

앱 대부분의 사용자 데이터는 기기 안에서 끝납니다. 이를 위해 core_storage 패키지에 JsonListStore를 만들었습니다. 목록을 저장하고 불러오고 지우는 정도의 앱이라면 이 구조로 충분했습니다.
모임각의 후보 목록, 이름추첨기의 항목, 문장수리소의 최근 기록처럼 개인 기기 안에서만 필요하고 다른 사용자와 공유하지 않는 데이터가 여기에 해당합니다.
로컬 저장은 단순하지만 데이터가 깨졌을 때 앱 전체가 멈추지 않도록 처리해야 했습니다. 읽기에 실패하면 빈 값으로 돌아가고, 잘못된 데이터는 버리는 쪽을 택했습니다. 작은 앱에서는 복잡한 복구 화면보다 다시 시작할 수 있게 만드는 편이 더 나았습니다.
4. 데이터는 세 층으로 나눴습니다

앱에서 사용하는 데이터는 번들, 로컬, 외부 API의 세 층으로 나눴습니다. 앱과 함께 배포되는 고정 데이터는 번들에 넣고, 사용자가 만든 데이터는 로컬에 저장합니다. 자주 바뀌는 공개 정보만 외부 API에서 가져옵니다.
외부 API를 사용할 때는 주소와 실패 시 폴백, 캐시 규칙을 함께 둡니다. API 하나가 잠시 멈췄다고 앱의 핵심 기능이 같이 멈추지 않도록 하기 위해서입니다.
공공데이터라고 해서 그대로 사용하지도 않습니다. 무료 호출 한도와 재배포·캐시 약관, 상업적 이용 조건을 확인하고, 가능하면 두 번째 출처도 함께 찾습니다. 공식 기관이 같은 기능의 앱을 이미 제공하는지도 확인합니다.
5. 만들 수 있는 앱과 만들지 않는 앱

서버를 두지 않는다는 조건 덕분에 주제 검증이 오히려 쉬워졌습니다. 사용자 한 명의 기기 안에서 핵심 경험이 완결되고, 외부 데이터가 필요하다면 공개 출처와 폴백이 있는 앱을 우선합니다.
반대로 기기끼리 실시간 동기화가 필요하거나, 로그인 없이는 의미가 없거나, 사람과 사람을 실시간으로 연결해야 하는 앱은 후보에서 제외합니다. 좋은 아이디어여도 현재 공장과 맞지 않으면 만들지 않습니다.
예전에는 아이디어를 정한 뒤 기술 구조를 고민했다면, 지금은 제약을 먼저 두고 그 안에서 가능한 주제를 찾습니다. 선택지는 줄었지만 에이전트가 판단해야 할 공간도 함께 줄었습니다.
6. 정리
서버를 두지 않은 결정은 비용 절감으로 시작했지만 저장 방식, 데이터 출처, 앱 주제까지 바꿨습니다. 제약이 답을 대신 주지는 않지만 만들지 않을 것을 빠르게 걸러주는 기준은 되었습니다.
다음 글에서는 여러 앱에서 이 제약을 유지하면서도 광고 코드를 반복하지 않도록 만든 구조를 다뤄보겠습니다.


답글 남기기