[TIL] Spring Boot 빌드 도구 — Gradle(Groovy) vs Gradle(Kotlin) vs Maven

Spring Initializr에서 선택하는 Gradle(Groovy), Gradle(Kotlin DSL), Maven 빌드 도구의 차이, Groovy/Kotlin DSL의 타입·IDE 체감 차이, 선택 기준을 정리한 글이다.

Spring Initializr에서 프로젝트를 만들 때 가장 먼저 고르는 항목 중 하나가 빌드 도구다. 세 가지 선택지는 이름만 다르지 않다. 각각 설정 파일 형식, 문법, 생태계가 달라서 팀 컨벤션과 취향에 따라 고르게 된다.

[친구하자] 한국 스타트업이 Stripe 대신 Paddle을 고른 이유

한국 법인으로는 Stripe 계정을 만들 수 없어 결제 모듈을 다시 찾아본 과정, PG와 MoR의 차이, 그리고 그중에서 Paddle을 선택한 이유를 정리합니다.

글로벌 결제를 붙이려다 보니, 개발자들이 가장 먼저 떠올리는 Stripe는 한국 법인으로 계정 생성이 불가능했다. 대안을 찾다 MoR(Merchant of Record) 개념을 알게 됐고, 그중 Paddle을 선택했다. 왜 Stripe가 안 되는지, MoR이 무엇인지, 왜 Paddle인지 정리한다.

[친구하자] PostgreSQL 호스팅과 ORM, 함께 써야 하는 이유

Supabase(관리형 PostgreSQL)와 SQLAlchemy(ORM)는 경쟁 관계가 아니라 인프라 레이어와 접근 레이어를 각각 담당한다. supabase-py 클라이언트만 쓸 때의 한계, 레이어 분리의 이점, 교체 가능한 구조까지 정리합니다.

데이터베이스를 선택할 때 “어떤 DB를 쓸까”에만 집중하기 쉽지만, 실제로는 어디에 둘 것인가(인프라)코드에서 어떻게 접근할 것인가(접근 방식) 를 따로 결정해야 한다. Supabase와 SQLAlchemy는 각각 다른 레이어를 담당하며, 둘을 함께 쓰면 한쪽을 교체할 때 다른 쪽에 영향을 주지 않는 구조를 만들 수 있다.

[Infra] 리버스 프록시와 Nginx — 왜 많이 쓸까?

리버스 프록시의 개념, 포워드 프록시와의 차이, Nginx를 많이 사용하는 이유, Spring Boot 연동 예시를 정리했다.

백엔드를 EC2에 배포할 때 Nginx를 앞단에 두고 Spring Boot로 요청을 넘기는 구성을 자주 본다.
클라이언트는 https://api.example.com에만 접속하고, 실제 애플리케이션은 127.0.0.1:8080에서 돌아간다.
이때 Nginx가 하는 일이 바로 리버스 프록시(Reverse Proxy)다.

[TIL] Celery + Redis 태스크 큐 — 도입 배경과 동작 방식

FastAPI BackgroundTasks의 한계를 경험하고 Celery + Redis 태스크 큐로 전환한 배경, Producer-Broker-Worker 구조, BackgroundTasks와의 비교, 운영 시 고려할 설정을 정리한 글이다.

무거운 비동기 작업을 FastAPI BackgroundTasks로 처리하다 보면, 서버 재시작 시 작업이 유실되고 재시도도 어렵다. Celery + Redis로 워커를 분리하면 태스크를 큐에 보관하고, 실패 시 재시도·수평 확장까지 운영 요구에 맞게 대응할 수 있다.

[TIL] Spring Security Filter Chain 구성 — addFilterBefore

Spring Security의 SecurityFilterChain에 커스텀 OncePerRequestFilter를 등록하는 방법, addFilterBefore/After로 순서를 제어하는 이유, @Bean + @Profile로 환경별로 분리하는 패턴을 정리한 글이다.

3편에서 OncePerRequestFilter로 “요청당 1회 검증” 필터를 만들었다면, 4편은 그 필터를 Spring Security의 SecurityFilterChain어느 위치로 넣을지 다룬다. 필터 순서가 바뀌면 인증/인가 결과가 달라질 수 있으므로, addFilterBefore로 기준 필터 앞에 명시적으로 끼우는 것이 안전하다.

[TIL] OncePerRequestFilter — 서블릿 필터 구현 패턴

Spring의 OncePerRequestFilter로 요청당 1회만 실행되는 서블릿 필터를 만드는 방법, shouldNotFilter()로 경로를 선택 적용하고 doFilterInternal()에서 체인을 이어가는 패턴을 정리한 글이다.

Spring에서 커스텀 필터를 만들 때 Filter를 직접 구현하면 forward/include 시 같은 요청에 필터가 여러 번 돌 수 있다. OncePerRequestFilter를 쓰면 요청당 한 번만 실행되고, shouldNotFilter()로 특정 경로를 건너뛰며, doFilterInternal()에서 검증 후 filterChain.doFilter()로 체인을 이어갈 수 있다.

[TIL] @ConfigurationProperties + @Validated — 설정값 검증과 fail-fast

@ConfigurationProperties와 @Validated로 설정값을 앱 시작 시 검증하는 방법, ${ENV_VAR}와 ${ENV_VAR:default}의 차이, 운영 환경에서 fail-fast로 배포 실패를 앞당기는 이유를 정리한 글이다.

운영 환경변수가 빠져 있어도 앱이 뜨고, 첫 요청에서야 터지는 상황은 디버깅 비용이 크다. @ConfigurationProperties@Validated를 붙이고 @NotBlank로 필수값을 선언하면, 배포 직후 시작 단계에서 바로 실패(fail-fast)시킬 수 있다.

[TIL] Spring Boot Actuator - 운영 노출 범위 제어

Spring Boot Actuator 엔드포인트를 운영 환경에 그대로 노출할 때 발생하는 보안 위험과, health 중심 최소 노출 원칙, 환경별 분리 설정, 네트워크/시큐리티 방어층까지 한 번에 정리한 글이다.

Spring Boot Actuator는 운영 관측에 매우 유용하지만, /actuator/env, /actuator/heapdump, /actuator/beans 같은 엔드포인트를 외부에 열어두면 민감 정보 유출로 이어질 수 있다. 운영에서는 필요한 최소 엔드포인트만 노출하고, 애플리케이션/네트워크/인증 계층에서 방어를 겹겹이 두는 것이 안전하다.

[TIL] null과 0은 다르다 — API에서 “데이터 없음”과 “값이 0”을 구분하는 법

API에서 미분석(null·무효 입력)과 분석 완료 후 점수 0을 구분하지 못해 생기는 조용한 버그, 변환 전 유효성 검증·JSON 직렬화·집계 분모 처리까지 정리한 글이다.

📝 TIL (Today I Learned)
null이나 빈 맵을 모두 Map.of()로 흡수하면, 미분석·점수 누락·합계 0인 분석이 한데 섞인다. 변환 전에 isValidScoreMap()으로 걸러내고, 무효면 null을 유지하면 집계·UI에서 의미가 살아난다.

Pagination