시작하기

iOS 프로젝트를 진행하다 보면 생각보다 자주 간단한 API 서버가 필요해진다. 회원가입 화면을 만들거나, 목록 조회 기능을 붙이거나, 이미지 업로드를 테스트할 때도 서버가 필요하다. 물론 실제 백엔드를 구축할 수도 있고, Supabase나 Firebase 같은 BaaS를 사용할 수도 있다. 하지만 작은 개인 프로젝트나 프로토타입 단계에서는 좋은 설계는 아니라고 생각한다.

특히 처음부터 특정 서비스에 의존하기 시작하면, 정작 내가 만들고 싶은 앱의 기능보다 인프라 설정과 서비스 사용법을 익히는 데 더 많은 시간을 쓰게 된다. 앱 개발을 위한 도구가 필요했는데, 어느 순간 도구를 사용하기 위한 공부를 하고 있는 상황이 되는 것이다.

그리고 내 서비스가 그 특정 도구에 감염되게 된다. 아무리 DIP를 잘 지키더라도 이미 ‘내정자’가 존재하는 이상, 개발 과정에서 서비스가 그 내정자로부터 자유로워질 수가 없다. 그래서 앱 개발 과정에서 가볍게 사용할 수 있는 개발용 서버를 직접 만들어 보기로 했다.

목표는 실제 운영 환경을 위한 백엔드가 아니라, 기능 개발과 테스트를 빠르게 진행할 수 있는 Mock Server에 가까운 도구를 만드는 것이다. 범용적이라서 특정 구현체가 사실상 의미를 잃을 정도로 얕은 서버가 목표다.

기존 프로젝트의 문제

사실 비슷한 프로젝트를 이전에도 만든 적이 있다. 당시에는 “일단 동작하는 것"을 목표로 개발했기 때문에 기능은 어느 정도 만족스러웠다. 하지만 시간이 지나 다시 코드를 살펴보니 구조적인 아쉬움이 많이 보였다.

가장 큰 문제는 경계가 불분명하다는 점이었다. 라우트는 어디까지 책임져야 하는지, 서비스는 어떤 역할을 해야 하는지, 저장소 구현은 어느 레이어에 위치해야 하는지 같은 기준이 명확하지 않았다. 기능을 추가할 때마다 새로운 코드가 기존 코드와 자연스럽게 연결되는 것이 아니라, 여기저기 이어 붙여지는 느낌이 강했다.

또 다른 문제는 데이터 저장 방식을 너무 일찍 결정했다는 것이다. 프로젝트 초기에 SQL을 도입했는데, 당시에는 합리적인 선택이라고 생각했다. 하지만 결과적으로는 서버가 제공해야 하는 기능보다 SQL 자체가 프로젝트의 중심이 되어버렸다.

CRUD 서버를 만들고 싶었던 것인지, SQL 기반 애플리케이션을 만들고 싶었던 것인지 경계가 흐려졌다. 이번 프로젝트에서는 이런 실수를 반복하지 않기 위해 의존성에 조금 더 신경 쓰기로 했다.

특정 데이터베이스 기술이나 저장 방식에 먼저 맞추는 것이 아니라, 서버가 어떤 역할을 해야 하는지부터 정의한 뒤 필요한 구현체를 붙이는 방향으로 접근하기로 했다.

설계 원칙 정리

프로젝트를 시작하기 전에 먼저 머릿속에 있던 생각들을 모두 적어 내려갔다. Mock Server라는 한 단어만으로는 분명히 중간에 길을 잃는다. 그래서 구현에 들어가기 전에 프로젝트의 성격과 목표를 먼저 써 내려갔다.

특히 이번 프로젝트에서는 “흐름이 명확한 코드"를 가장 중요하게 생각했다. 코드를 읽었을 때 데이터가 어디서 생성되고, 어떤 과정을 거쳐 전달되며, 최종적으로 어디에 저장되는지 쉽게 추적할 수 있어야 한다고 생각했다.

아무리 재사용성이 높고 추상화가 잘 되어 있어도 흐름을 이해하기 어렵다면 유지보수 비용이 커질 수밖에 없다. 추상화가 코드의 흐름을 숨기기 시작하면 문제가 생긴다. 그래서 이번 프로젝트에서는 재사용성보다도 흐름을 쉽게 추적할 수 있는 구조를 우선순위에 두었다.

AI와 함께 개발하기

또 하나의 목표는 AI와 함께 개발하는 환경을 구축하는 것이었다. 최근에는 Cursor나 Codex 같은 AI 기반 개발 도구를 적극적으로 사용하고 있다. 그런데 사용하면서 느낀 점은, AI에게도 프로젝트의 방향성을 알려주는 문서가 필요하다는 것이었다.

사람이 새로운 프로젝트에 합류하면 프로젝트의 규칙과 컨벤션을 먼저 설명해 주듯이, AI도 마찬가지였다. 프로젝트의 방향성을 문서로 제공하지 않으면 매번 같은 설명을 반복해야 하고, 이전에 내렸던 설계 결정을 계속 다시 설명해야 한다.

그래서 가장 먼저 루트 AGENTS.md를 작성했다.

# Project Overview

This project is a lightweight development server for app development and local testing.

...

# AI Guidance

- Prefer simpler solutions when possible.
- Avoid introducing unnecessary abstractions.
- Keep execution flow easy to trace.

초기 AGENTS.md는 기술 스택, 아키텍처 원칙, 테스트 전략, 에러 처리 방식 등을 정의하는 수준으로 시작했다. 이후 프로젝트가 커지면서 모듈별 AGENTS.md를 추가하고, 규칙도 조금씩 발전시켜 나갈 예정이다.

초기 아키텍처

처음에 생각한 구조는 단순했다.

Route
Service
Implementation

각 레이어의 책임을 명확하게 분리하고 싶었다. Route는 HTTP 요청과 응답만 처리한다. Service는 애플리케이션의 흐름과 유즈케이스를 담당한다. Implementation은 실제 기술 구현을 담당한다.

앞으로의 계획

다음 순서대로 기능을 추가할 예정이다.

  • System 모듈
  • DB 모듈
  • File Storage 모듈
  • Auth 모듈
  • 테스트 보강

레코드의 책임은 누구에게 있는지, ID는 누가 생성해야 하는지, 저장소 구현이 외부로 노출되지 않게 하려면 어떤 구조를 선택해야 하는지 등을 고민했다. 다음 개발일지에서는 DB 모듈을 설계하면서 겪었던 시행착오와 설계 변경 과정을 정리해보려고 한다.