BSSJ 아키텍처, 왜 지금 이 구조가 맞았는지
서버는 많지 않고, 운영은 단순해야 하고, 화면 경험은 분리하고 싶을 때가 있다.
BSSJ 구조는 딱 그 조건에서 출발했다.
이 글은 docs/architecture.md(2026-03-09 기준) 내용을 바탕으로,
왜 지금 구조를 이렇게 가져갔는지 한 번에 보이게 정리한 버전이다.
30초 요약
- 사용자 화면은
Web/CMS로 분리 - 백엔드는
Spring Boot 단일 프로세스로 통합 - 공개 API는
/api/*, 관리자 API는/cms/*로 경계 분리 - 데이터 저장은
MySQL, 파일 저장은S3로 역할 분리
한 줄로 정리하면 이거다.
“UX는 분리하고, 런타임은 통합한다.”
전체 구조 먼저 보기
요청 흐름은 단순하다.
- Web 사용자는 공개 화면 + 공개 API 사용
- CMS 사용자는 관리자 화면 + 인증 API 사용
- 두 경로 모두 같은 백엔드 프로세스로 들어옴
- 백엔드가 MySQL/S3로 책임 나눠 처리
구조를 단순하게 잡아둔 덕분에 배포 포인트, 장애 대응 포인트도 같이 줄었다.
왜 FE는 분리하고, BE는 합쳤을까?
이 질문을 제일 많이 받는다.
“하나의 서비스면 그냥 전부 합치면 되는 거 아닌가?”
실제로는 반대로 보는 게 더 맞다.
- 화면 목적이 다르다.
방문자용 Web과 관리자용 CMS는 사용자 흐름이 다르다. 그래서 FE는 분리하는 게 맞다. - 운영은 단순해야 버틴다.
작은 팀에서 JVM을 둘로 나누면 배포/모니터링/장애 대응 비용이 빠르게 커진다.
그래서 지금은 이렇게 정리했다.
- FE:
apps/web/frontend,apps/cms/frontend분리 - BE:
apps:web:backend하나로 통합 실행
현재 규모에서는 이 구성이 속도와 안정성 사이 균형이 제일 좋았다.
요청 흐름을 실제로 보면
방문자(Web)
- 사용자가 Public Web 접속
- Nginx가 정적 리소스 응답
- 화면에서
/api/*호출 - 백엔드가 MySQL 조회 후 JSON 반환
관리자(CMS)
- 관리자가 CMS 접속
- Nginx가 CMS 정적 리소스 응답
POST /cms/auth/login으로 JWT 발급- 이후
/cms/*호출 시 토큰 검증 - 필요 시 S3 파일 처리
핵심은 명확하다.
인증은 CMS 경로에 집중하고, 공개 조회는 가볍게 유지한다.
백엔드 모듈 구조: 통합이지만 경계는 유지
실행 프로세스는 하나지만, 내부 모듈 경계는 분명하게 나눴다.
apps:web:backend(실행 엔트리)apps:cms:backend(java-library)apps:common:mysqlapps:common:core
의존 관계는 아래처럼 고정돼 있다.
web/backend -> cms/backendweb/backend -> common/mysql -> common/corecms/backend -> common/mysql
즉 구조의 핵심은 이거다.
프로세스는 하나, 경계는 명확하게.
패키지 구조도 도메인 중심으로 정리
초기 레이어 구조(controller/service/repository)에서는 수정 범위가 넓어질수록 이동 비용이 컸다.
그래서 지금은 도메인 기준으로 재정렬했다.
com.bssj.webapi:video,content,churchinfo,settings,menu,modal,manager,commoncom.bssj.cms:auth,video,bulletin,menu,staff,worshiptime,mainpage,upload,bible,manager,common
그리고 cms/manager는 domain/port/infra로 나눠 hexagonal 패턴을 적용했다.
보안/멀티 교회 관점에서 중요한 점
인증 정책은 URL 경계와 같이 간다.
/api/*: 인증 없음 (공개 조회)/cms/*: JWT 필수 (/cms/auth/**제외)
JWT 안에 cid(churchId)를 담아 교회 단위 데이터 격리를 유지한다.
지금은 단일 운영에 가까워도, 이 경계가 있어야 멀티 교회 확장 비용이 줄어든다.
인프라/배포: 작게 시작하고 단단하게 유지
현재 운영 기준은 단일 EC2(t3.small)다.
- Nginx: 정적 파일 + 프록시
- Unified Backend:
:8080 - MySQL: 로컬
- S3: 외부 스토리지
CI/CD도 목적 중심으로 가져갔다.
- CI (
developPR): 빌드/테스트 품질 가드 - CD (
mainpush): 빌드 -> 전송 -> 서비스 재시작
대규모 분산보다, 운영 안정성을 먼저 챙긴 구성이라고 보면 된다.
이 구조의 장점과 리스크
장점
- 운영 포인트 감소: 프로세스/배포 대상 단순화
- 비용 효율: JVM/Tomcat/Hikari 중복 제거
- 개발 속도: FE 분리로 작업 충돌 최소화
리스크
- 경계 관리 실패 시 단일 앱 비대화
/api와/cms정책이 흐려지면 보안/권한 리스크 증가
그래서 운영 원칙은 계속 이대로 가져간다.
- 런타임 통합 유지
- 모듈/도메인 경계 강화
- 인증 정책 URL 규칙 강제
다음 단계 우선순위
- CMS 업로드를 presigned URL 중심으로 전환
- Swagger를
/api와/cms기준으로 명확히 분리 - 멀티 교회 권한 모델(전역/교회 관리자) 구체화
정리하면 BSSJ 구조는 “완벽한 이상형”보다,
지금 팀이 운영 가능한 최적점을 목표로 잡은 아키텍처다.
그리고 확장을 위한 경계(모듈/인증)는 이미 깔아둔 상태다.