In-Memory DB 구현 1편 - HTTP 없이 TCP 소켓 직접 제어하기

들어가며 요즘 대부분의 개발자들이 바이브 코딩 또는 못해도 gpt나 클로드, 제미나이 같은 LLM을 사용해서 개발을 할 것이다. AI가 코드를 구현해주면 개발자의 검증이 반드시 필요한데 성능 문제, 비즈니스 및 도메인 지식, 소프트웨어 구조 설계 등이 AI 시대의 개발자로서 필요한 역량이라고 생각한다. 코드가 그냥 굴러만 가더라도, 병목현상이 벌어지는 구간이 어디인지 검증을 해봐야하고 비즈니스가 어떻게 흘러가는지와 도메인 지식을 결합하여 코드를 어떻게 처리해야 좋을지, 그리고 복합적으로 따져봤을 때 최적의 아키텍처나 구조 등을 직접 결정해야할 것이다. ...

2026년 1월 28일 PM03:29 · PolarBear

Garbage Collection 이해하기

들어가며 지난 포스팅에서는 JVM의 전체적인 메모리 구조(Runtime Data Area)에 대해 공부한 내용을 정리했다. JVM이 OS로부터 메모리를 할당받고, 이를 용도에 따라 Method, Heap, Stack 등으로 나누어 관리한다는 것을 알 수 있었다. 오늘은 그중에서도 객체가 저장되는 가장 중요한 공간인 힙(Heap) 영역과, 이 공간을 자동으로 관리해 주는 가비지 컬렉션(Garbage Collection) 에 대해 학습하고자 한다. C, C++ 같은 언어에서는 개발자가 직접 메모리를 할당하고 해제해야 했지만 자바는 GC가 있기에 개발자가 비즈니스 로직에 조금이라도 더 집중할 수 있을 것이라 생각한다. 서버의 성능 문제나 메모리 누수 등의 이슈를 해결하기 위해서는 이 메커니즘을 반드시 이해해야 한다. 이번 포스팅을 통해 힙 영역의 구조와 GC의 동작 원리를 정리해보겠다. ...

2026년 1월 15일 PM04:09 · PolarBear

JVM 구조 이해하기

들어가며 예전에 남궁성 저자의 “자바의 정석” 책을 통해 공부하며 기본기를 다졌지만, 실무를 하다 보니 더 탄탄한 베이스가 필요함을 느꼈다. 처음 정독할 당시에는 책이 워낙에 두꺼웠기에 jvm, 스레드, 람다, 스트림, 네트워크 등 후반부 챕터를 빠르게 훑고 지나갔던 것이 아쉬움으로 남았다. 이번 기회에 다시 자바의 정석 책을 펼쳐보며 앞서 말한 챕터들과, 개인적으로 헷갈리거나 잊어버린 지식들에 대해서도 복습해보며 차근차근 포스팅을 해 볼 예정이다. 하지만 책에서는 자세하게 나와있지 않을 부분도 존재할 수 있어 각 키워드별로 공식문서도 참고할 생각이다. ...

2026년 1월 8일 AM12:27 · PolarBear

Spring에서 Node.js(Fastify)으로 전환하기(5) - Playwright로 E2E 테스트 자동화

들어가며 지난 글에서 Plan 도메인의 CRUD API를 모두 구현했다. 이제 과제를 시작하기 전에 진행했었던 Playwright MCP를 에이전트에 붙여 E2E테스트 자동화 하는 과정을 현재 앱에 적용하여 보겠다. Playwright Playwright는 마이크로소프트에서 만든 브라우저 자동화 도구다. 원래는 웹 페이지를 자동으로 클릭하고, 폼을 채우고 스크린샷을 찍는 등의 E2E 테스트를 위해 만들어졌다. Selenium이나 Puppeteer 같은 도구와 비슷하지만 다음과 같은 몇 가지 장점이 있다. 빠른 실행 속도 - 다른 도구들보다 빠르다 안정적인 테스트 - 요소가 나타날 때까지 자동으로 기다려준다 다양한 브라우저 지원 - Chromium, Firefox, WebKit 모두 지원 API 테스트 가능 - 브라우저 없이도 HTTP 요청을 보낼 수 있다 플레이라이트는 request fixture라는 걸 제공해서, 실제 브라우저를 띄우지 않고도 API 테스트를 할 수 있다. ...

2025년 11월 14일 PM05:23 · PolarBear

Spring에서 Node.js(Fastify)으로 전환하기(4) - Plan 도메인 구현하기

들어가며 지난 글에서 환경변수 관리와 데이터베이스 플러그인 설정까지 마쳤다. 이제 비즈니스 로직을 구현할 차례다. 스프링에서는 Controller, Service, Repository로 계층을 나눠서 개발했었는데 fastify에서도 비슷한 구조를 유지하려고 했다. Controller 대신 Routes라고 부르고, DTO 클래스 대신 Zod 스키마를 사용하는 등 약간의 차이점은 있었다. 이번 글에서는 Plan 도메인의 CRUD API를 node.js 환경으로 전환했던 과정을 정리해보려고 한다. Zod를 사용하여 스키마 작성 핵심로직, 라우트 등을 먼저 구현하기 전에 스프링 코드와 대칭되는 DTO를 작성했다. 라우트 내부에서 schema 블럭에 요청DTO의 형식을 정할 수도 있지만 Zod라는 것을 사용해봤다. ...

2025년 11월 13일 PM10:34 · PolarBear

Spring에서 Node.js(Fastify)으로 전환하기(3) - 환경변수와 데이터베이스 플러그인 설정 Feat. Spring vs Fastify

들어가며 지난 글에서 prisma를 설치하고 마이그레이션까지 성공했다. 이제 실제로 애플리케이션에서 데이터베이스를 사용할 수 있도록 연동 작업을 진행해야 한다. 스프링 부트에서는 application.yml에 데이터베이스 설정만 해두면 자동으로 연결이 되고, 생성자 주입으로 Repository를 주입받아 사용하면 끝이었다. 하지만 fastify는 그런 자동화가 없다. 모든 걸 직접 설정해야 한다고 한다. 이번 글에서는 환경변수를 타입 안전하게 관리하고, prisma를 fastify 플러그인으로 등록하는 과정을 정리해보려고 한다. 환경변수 관리의 문제 기존에는 server.ts에서 이렇게 환경변수를 사용하고 있었다. const PORT = Number(process.env.PORT) || 3000; 문제는 이렇게 사용하면 ...

2025년 11월 12일 PM09:25 · 🛠 업데이트: 2025년 11월 13일 PM09:25 · PolarBear

Spring에서 Node.js(Fastify)으로 전환하기(2) - Prisma 연동

들어가며 이전 포스팅에서 프로젝트 환경 셋업을 진행한데 이어, 데이터베이스 연동을 해보려고한다. 스프링에서는 jpa와 hibernate를 사용해서 엔티티 관리가 비교적 편했는데, node 생태계에서는 어떤 ORM이 좋을지 고민이 많았다. TypeORM도 고려했지만 이전에 잠깐이나마 회사에서 prisma를 사용해보기도 했고, 타입 안정성과 직관적인 스키마 작성 방식이 마음에 들어서 prisma로 결정했다. 이번 글에서는 prisma를 처음 설정하면서 겪었던 시행착오와 해결 과정을 공유하려고 한다. Prisma 초기 설정 패키지 설치 Prisma를 사용하려면 두 가지 패키지가 필요하다. npm install prisma @prisma/client prisma: CLI 도구 및 스키마 관리 @prisma/client: 실제 쿼리를 실행하는 클라이언트 Prisma 초기화 설치가 끝나면 초기화 명령어를 실행한다. ...

2025년 11월 11일 PM09:59 · PolarBear

Spring에서 Node.js(Fastify)으로 전환하기(1) - 프로젝트 환경 셋업

들어가며 최근 스프링부트로 구현된 REST API 프로젝트를 node.js, fastify 환경으로 마이그레이션 하고, 클로드 코드 및 코파일럿 등의 에이전트에 PlayWright MCP서버를 연동하여 E2E 테스트를 자동화하는 과제를 진행하게 되었다. 과제 진행을 하면서, 새롭게 학습하고 그 과정 속에서 힘들었던 부분 등을 기록하고자 한다. 이번 글에서는 본격적인 마이그레이션 작업에 앞서, Node.js + TypeScript + Fastify 기반의 프로젝트 환경을 세팅한 과정을 정리해보려고 한다. 목표 기존 Spring Boot 프로젝트는 전형적인 레이어드 아키텍처로 구성되어 있다. Controller -> Service -> Repository -> Entity (JPA) 이 구조를 최대한 유지하면서 node 환경으로 옮기는 게 우선적인 목표다. 다만 스프링의 의존성 주입이나 자동 설정 같은 편의 기능이 없으니 그 부분을 어떻게 해결할지 고민이 많았다. ...

2025년 11월 10일 PM07:55 · PolarBear

Facade 패턴, SRP 원칙 기반으로 리팩토링을 해보자

들어가며 현재 서비스중인 AuthService가 387줄의 거대한 God Object로 성장해버렸다. 로그인, 회원가입, 소셜 로그인, 이메일 찾기, 비밀번호 변경 등 인증 관련 모든 기능을 한 클래스에서 처리하다 보니 테스트도 어렵고 수정할 때마다 긴 코드를 찾아봐야 하다보니 유지보수에 있어서 너무 불편했다. 이를 SRP 원칙에 따라 3개 서비스로 분리하고, Facade 패턴으로 재구성한 과정을 기록했다. 문제 상황 God Object가 된 AuthService AuthService - 387줄 - 의존성: 11개 - 담당 책임: 6가지 1. 로그인/로그아웃 (토큰 관리) 2. 회원가입 (검증 + 외부 API + DB 저장) 3. 소셜 로그인 (카카오/구글/네이버) 4. 이메일/전화번호 찾기 5. 이메일 인증 발송/확인 6. 비밀번호 변경 한 클래스가 6가지 책임을 가지고 있고 명백한 SRP 위반이다. ...

2025년 11월 3일 PM08:56 · PolarBear

템플릿 메서드 패턴을 활용하여 리팩토링을 해보자

들어가며 현재 사내에서 서비스중인 앱의 백엔드 코드에서 중복되는 코드가 심하게 일어나는 부분이 있었다. 회원과 관련된 추가정보(경력, 학력, 논문 등)들이 총 7개가 있는데 이 7개의 도메인들의 CRUD 로직이 100% 동일하다는 것에 템플릿 메서드 패턴을 적용하여 리팩토링을 해보면 어떨까 생각이 들었다. 추가정보 도메인 총 7개의 기존 서비스 로직의 코드 라인에는 생성, 조회, 리스트조회, 수정, 일괄 수정, 삭제, 일괄 삭제, 소프트 삭제, 삭제복원을 포함하여 약 210줄의 코드가 동일한 로직으로 중복되고 있었다. 문제 상황 분석 중복 코드의 심각성 7개의 서비스 클래스가 거의 동일한 구조를 가지고 있었다. 예를 들어 경력(Career) 서비스와 학력(Education) 서비스를 비교해보면 다음과 같았다. ...

2025년 10월 30일 PM09:13 · PolarBear