프로젝트 기술 스택 선정
이번 프로젝트는 지역 기반 커뮤니티 서비스이며, 초기에는 REST API 기반 백엔드 서버를 구축하고 이후 모바일 앱 연동까지 고려하고 있다. 그래서 단순히 익숙한 기술을 고르기보다는, 확장성, 유지보수성, 앱 연동 가능성, 배포 편의성을 기준으로 기술 스택을 선택했다.

Java 21
이전 프로젝트에서는 Java 17을 사용했지만, 이번 프로젝트에서는 Java 21을 선택했다. Java 21도 Java 17과 마찬가지로 LTS 버전이기 때문에 장기적으로 안정적인 유지보수가 가능하다.
vs Java 17
Java 17과 비교했을 때 Java 21의 가장 큰 장점은 최신 기능들이 더 안정적으로 반영되었다는 점이다. 대표적으로 Virtual Thread가 정식 기능으로 포함되어, 많은 요청을 처리하는 서버 애플리케이션에서 더 가볍고 효율적인 동시성 처리가 가능해졌다. 또한 switch 문 개선, Record Pattern, Sequenced Collection 같은 기능들이 추가되어 코드를 더 간결하고 읽기 쉽게 작성할 수 있다.
즉, Java 17이 안정적인 선택지였다면 Java 21은 그 안정성을 유지하면서도 성능과 개발 편의성을 더 높인 버전이라고 볼 수 있다.
LTS 버전
LTS는 Long Term Support이라는 뜻으로, 장기간 지원되는 버전이라는 뜻이다.
Java는 계속 새 버전이 나오지만 ,모든 버전을 오래 지원하지 않기에, 보통 오래 안정적으로 사용할 수 있는 LTS 버전을 많이 사용한다.
Virtual Thread
Virtaul Thread는 Java 21에서 정식으로 들엉노 기능이다.
기존에는 요청 하나를 처리할 때 운영체제의 무거운 스레드를 사용하는 경우가 많았는데, Virtaul Thread는 더 가벼운 스레드를 사용해서 많은 요청을 효율적으로 처리할 수 있다.
Record Pattern
Java 21에서는 record 관련 기능도 계속 개선됐다. 프로젝트에서는 요청/응답 DTO를 작성할 때 record를 활용해 불필요한 코드를 줄이고, 데이터 전달 객체를 더 간결하게 표현할 수 있다.
Sequenced Collection
Sequenced Collection은 Java 21에서 추가된 컬렉션 관련 기능이다. 쉽게 말해 순서가 있는 컬렉션을 더 일관되게 다룰 수 있게 해주는 기능이다.
예를 들어 List, LinkedHashSet처럼 순서가 있는 자료구조에서 첫 번째 값, 마지막 값의 동작을 더 통일된 방식으로 사용이 가능하다.
list.getFirst();
list.getLast();
list.reversed();
Spring Boot 4.0.6
이전에는 Spring Boot 3.5 버전을 사용했지만, 이번 프로젝트에서는 Spring Boot 4.0.6을 선택했다. Spring Boot 3.5도 충분히 안정적인 버전이지만, Spring Boot 4는 더 최신 Spring 생태계를 기반으로 한다는 장점이 있다.
Spring Boot 4는 Spring Framework 7 기반으로 동작하며, 최신 Java 환경과 더 잘 맞도록 개선되었다. 또한 기존에 사용하던 인증, 검증, 데이터베이스 연동, REST API 개발 방식은 그대로 유지하면서도 내부 구조와 의존성들이 최신 버전으로 정리되어 있다.
즉, Spring Boot 3.5가 안정적인 실무형 버전이라면, Spring Boot 4.0.6은 앞으로의 확장성과 최신 기술 호환성을 고려한 선택이라고 볼 수 있다. 모바일 앱 연동, JWT 인증, API 확장 등을 계속 추가할 예정이기 때문에 처음부터 최신 버전으로 개발 환경을 구성했다.
Gradle - Groovy
빌드 도구는 Gradle을 선택했다. Gradle은 Maven보다 설정이 유연하고 빌드 속도 측면에서도 장점이 있다. Spring Boot 프로젝트에서 기본적으로 많이 사용되며, 의존성 관리와 테스트, 빌드 자동화에 적합하다.
Supabase PostgreSQL
데이터베이스는 MySQL, MongoDB 등 다른 선택지도 있었지만, Supabase PostgreSQL을 사용했다. 이번 프로젝트에는 실무에서 많이 쓰는 PostgreSQL에 더 익숙해지고 싶었다.
PostgreSQL은 관계형 데이터베이스이기 때문에 사용자, 게시글, 댓글, 좋아요, 지역 정보처럼 서로 관계가 명확한 데이터를 다루기에 좋다. 또한 데이터 정합성이 중요하고, 복잡한 조회가 필요한 커뮤니티 서비스와 잘 맞는다.
vs MySQL
PostgreSQL, MySQL 모두 관계형 데이터베이스이다. 사용자, 게시글, 댓글 등 서로 관계가 있는 데이터를 저장 할 때 사용한다. 특히 MySQL은 사용하기 쉽고, 자료가 많아 일반적인 웹 서비스에 많이 사용되어 입문하기 편하다는 장점이 있다.
PostgreSQL은 데이터 정합성, 복잡한 조회, 확장 기능에 강한 데이터베이스이다.
커뮤니티 서비스에는 1:N의 관계가 많다. 예를 들어 사용자 1명이 게시글 여러개를 작성 할 수 있고, 게시글 1개에 댓글이 여러개 작성될 수 있다.
이러한 관계가 많아질수록 데이터가 정확하게 저장되고 조회되는 것이 중요한데, PostgreSQL은 이런 관계형 데이터와 복잡한 조회에 강점이 있다.
PostgreSQL 장점
복잡한 조회에 강함
PostgreSQL은 SQL 표준 기능과 고급 쿼리 기능을 폭 넓게 지원한다. 예를 들면 여러 테이블을 JOIN해서 조회 한다던지, 게시글 수 같은 집계, 조건별 정렬과 페이징 등이 있다. 커뮤니티 서비스에서는 단순히 게시글만 가져오는게 아니라 이러한 조회가 필요할 것이다.
JSON 데이터에 유연
MySQL도 JSON을 다룰 수 있지만, PostgreSQL이 JSON을 더 강력하고 유연하게 다루는 편이다.
PostgreSQL은 jsonb 타입을 제공하고 내부적으로 인덱스를 사용해 JOSN 내부 값 검색을 효율적으로 할 수 있다. 공식 문서에서도 jsonb 데이터의 키나 값을 효율적으로 검색하기 위해 GIN 인덱스를 사용할 수 있다고 설명한다.
MySQL도 JSON 타입은 있지만, JOSN 컬럼 자체를 바로 일반 컬럼처럼 인덱싱 하기보다는 특정 값을 직접 활용하는 방식을 많이 사용한다. 그래서 JSON을 많이 활용하는 구조에서는 PostgreSQL이 더 자연스럽다.
Supabase
Supabase를 선택한 이유는 PostgreSQL을 클라우드 환경에서 쉽게 사용할 수 있기 때문이다. 직접 DB 서버를 설치하고 관리하지 않아도 되고, 초기 개발 단계에서 빠르게 데이터베이스를 구성할 수 있다. 나중에 모바일 앱이나 웹 클라이언트와 연동할 때도 관리 화면, 인증 기능, API 연계 가능성 등에서 장점이 있다.
정리
실제 데이터베이스 = PostgreSQL
PostgreSQL을 관리해주는 클라우드 서비스 = Supabase
Java 객체와 DB를 연결해주는 ORM = JPA
Spring Data JPA
ORM으로는 Spring Data JPA를 사용했다. SQL을 직접 작성하는 방식도 가능하지만, JPA를 사용하면 객체 중심으로 데이터를 다룰 수 있어 도메인 구조를 설계하기 좋다.
예를 들어 User, Post, Comment 같은 엔티티를 만들고 이들 간의 관계를 코드로 표현할 수 있다. 반복적인 CRUD 코드도 줄일 수 있어 개발 생산성이 높아진다. 다만 복잡한 쿼리가 필요한 경우에는 JPQL이나 QueryDSL 같은 방식을 함께 고려할 수 있다.
Spring Security, JWT
보안은 Spring Security를 기반으로 구성할 예정이다. 커뮤니티 서비스에서는 로그인, 회원별 권한, 게시글 작성 권한, 토큰 검증 같은 기능이 필수적이다.
특히 모바일 앱까지 고려하면 세션 기반 인증보다는 JWT 방식이 더 적합하다. JWT는 서버가 로그인 상태를 직접 저장하지 않고 토큰을 통해 사용자를 인증할 수 있기 때문에, 웹과 모바일 앱 모두에서 사용하기 좋다.
Spring Validation
사용자 입력값 검증을 위해 Spring Validation을 사용했다. 회원가입, 로그인, 게시글 작성, 댓글 작성 같은 API에서는 잘못된 값이 들어오는 경우를 반드시 처리해야 한다.
예를 들어 이메일 형식, 비밀번호 길이, 게시글 제목의 빈 값 여부 등을 DTO 단계에서 검증하면 컨트롤러와 서비스 코드가 더 깔끔해진다. 또한 API 응답의 일관성을 유지하기에도 좋다.
보일러 플레이트 코드란 기능 자체는 단순한데, Java 문법상 계속 반복해서 작성해야하는 코드를 의미한다.
Lombok, Spring Boot DevTools
Lombok은 반복적인 getter, setter, constructor 코드를 줄이기 위해 사용했다. 엔티티나 DTO가 많아질수록 보일러플레이트 코드가 늘어나는데, Lombok을 사용하면 코드가 훨씬 간결해진다.
Spring Boot DevTools는 개발 중 서버 재시작과 변경 사항 반영을 편하게 하기 위해 사용했다. 개발 생산성을 높이는 보조 도구이다.
REST API
REST API는 웹 프론트엔드, 모바일 앱, 외부 서비스와 연동하기 쉽기에, API 스타일은 REST API로 설계했다.
현재는 백엔드 서버 중심으로 개발하더라도, 나중에 React 웹, Android/iOS 앱, 또는 Flutter/React Native 앱이 같은 API를 사용할 수 있다. 즉, 클라이언트가 바뀌어도 백엔드 API는 재사용할 수 있다는 장점이 있다.
Vite
Vite는 가볍고 빠르게 React 프론트엔드를 만들기 좋은 도구이다. Next.js는 라우팅, SEO, 백엔드 기능까지 포함한 React 프레임워크로 많은 기능을 갖고 있다.
하지만 이번 프로젝트는 Spring Boot 백엔드 서버가 따로 있고, 프론트엔드는 그 API를 호출하는 역할이 중심이다.
그래서 처음부터 Next.js처럼 많은 기능을 가진 프레임워크보다, React 화면 개발에 집중할 수 있고 설정이 비교적 단순한 Vite가 더 적합하다고 판단했다.
정리
이번 기술 스택은 빠른 개발과 장기적인 확장을 모두 고려해서 선택했다. Java와 Spring Boot는 안정적인 백엔드 서버를 만들기 좋고, PostgreSQL은 관계형 데이터가 많은 커뮤니티 서비스에 적합하다. Supabase는 초기 데이터베이스 운영 부담을 줄여주며, REST API 구조는 이후 웹과 모바일 앱 연동을 쉽게 만든다.
결국 핵심은 백엔드를 특정 화면이나 클라이언트에 종속되지 않게 만드는 것이다. 지금은 서버와 API를 중심으로 개발하고, 이후에는 Vite 기반 웹 프론트엔드나 모바일 앱을 같은 API에 연결하는 방식으로 확장할 수 있다.