SSE란? 실시간 이벤트 전달 프로토콜 (Server-Sent Events)

SSE(Server-Sent Events)란 무엇인가 SSE는 Server-Sent Events의 약자로, 서버가 클라이언트로 실시간 데이터를 단방향으로 푸시(push)할 수 있게 해주는 웹 기술임 클라이언트가 먼저 요청을 보내고 서버는 그 연결을 끊지 않은 채, 새로운 데이터가 생길 때마다 지속적으로 응답을 보내는 방식임 주로 실시간 알림, 주식 시세 업데이트, 라이브 피드 등 서버에서 클라이언트로 일방적인 데이터 전송이 필요한 경우에 매우 유용함 SSE vs 웹소켓, 그리고 한계 SSE는 실시간 이벤트 전송에 유용하지만 만능은 아님. 웹소켓과 비교했을 때 명확한 장단점이 존재함 ...

October 25, 2025

NestJS 핵심 개념과 11.x 변화 정리 — 구조, DI, 데코레이터, 성능 업데이트

개요 NestJS는 대규모 서버 애플리케이션을 위한 구조화된 Node.js 프레임워크임 핵심은 Angular 스타일의 아키텍처, 강력한 의존성 주입 컨테이너, 데코레이터 기반 메타프로그래밍 조합 팀 규모가 커질수록 일관성과 유지보수성이 살아나는 타입스크립트 퍼스트 선택지임 구조적 강제의 이점 Nest는 모듈 Module, 컨트롤러 Controller, 서비스 Service 구조를 강제함 계층 분리 패턴 BLL, DAL, 도메인 레이어 등 적용 용이 아키텍처가 일관되게 유지되어 4~10명 규모 팀에서 코드 스타일과 책임 경계가 흐트러지지 않음 Fastify, Express 같은 미니멀 프레임워크 대비 생산성과 일관성 측면에서 팀 단위 효율 우위 ...

December 19, 2025

백오프 Backoff 재시도 전략 정리 고정·선형·지수·지터

개요 백오프는 실패한 작업을 즉시 재시도하지 않고 일정 시간 대기 후 다시 시도하는 전략을 말함 연속 실패 시 대기 시간을 점진적으로 늘려 서비스와 네트워크에 가해지는 부하를 낮추는 목적 RPC, 데이터베이스, 외부 API 호출, 트랜잭션 재시도 등에서 일반적으로 사용 왜 쓰는가 과부하 방지 실패 직후 동시 재시도를 막아 서버와 네트워크 폭주를 예방 일시적 장애 흡수 순간적인 지연이나 혼잡이 해소될 시간을 벌어 성공 확률을 높임 비용 절감 불필요한 재시도 횟수와 리소스 낭비 감소 대표 백오프 패턴 고정 백오프 Fixed 매번 동일 대기 시간 사용 예) 1초 → 1초 → 1초 선형 백오프 Linear 시도할 때마다 일정 간격으로 증가 예) 1초 → 2초 → 3초 → 4초 지수 백오프 Exponential 보통 2배로 증가하는 지수 증가 사용, 실무에서 기본값으로 가장 흔함 예) 1초 → 2초 → 4초 → 8초 → 16초 지수 백오프 + 지터 Jitter 지수 증가에 무작위성을 섞어 동시 재시도 동기화를 깨뜨림 예) 1초 → 2.3초 → 4.1초 → 8.6초 실전 포인트 동시성 환경에서는 지터 필수 동일한 주기 백오프만으로는 다수 클라이언트가 같은 타이밍에 몰려 서버를 다시 두들김 상한 설정 최대 대기 시간과 최대 재시도 횟수 캡을 두어 꼬리 길어짐 방지 실패 예산과 타임아웃 연계 전체 호출 타임아웃 내에서 재시도 예산을 배분, 1회 호출과 재시도들이 전체 SLA를 초과하지 않도록 관리 멱등성 보장 재시도 가능한 작업은 멱등성을 만족해야 안전, 아니면 보상 로직 필요 서버 힌트 활용 Retry-After 등 서버가 제시하는 대기 힌트가 있으면 우선 적용 지터 방식 선택 전체 구간 무작위 분포 Full jitter가 단순하고 효과적이라는 보고가 많음 간단 예시 아래는 지수 백오프의 최소 구현 예시이며, 지터와 최대 대기 시간 제한은 상황에 맞게 추가 권장 ...

November 28, 2025

Prisma where 관계 필터 some vs every 동작 차이와 주의점

관계형 데이터에서 Prisma의 where 절은 자식 레코드 기준으로 부모를 거르는 필터를 제공함. 특히 some과 every는 겉보기엔 비슷하지만 결과 집합을 크게 바꾸는 핵심 차이가 있음. 단일 필드만으로 필터링해도 동일하지 않을 수 있어 주의 필요 개념 some 관계된 레코드 중 적어도 하나가 조건을 만족하면 부모 포함 존재성 검사에 해당, 하나라도 매칭되면 true every 모든 관계된 레코드가 조건을 만족해야 부모 포함 단 하나라도 위배되면 제외됨 관계된 레코드가 하나도 없으면 vacuously true로 간주되어 조건 만족으로 처리됨 동작 원리 some은 존재량화, every는 전칭량화에 해당함 차이는 자식 레코드가 0개이거나 2개 이상일 때 두드러짐. 1개일 때는 조건이 동일하다면 결과가 같아질 수 있음 특히 자식이 없는 경우 every는 기본적으로 참으로 평가되어 부모가 포함됨. 빈 결과를 제외하려면 추가 조건 필요 간단 예시 model Post { id Int @id @default(autoincrement()) title String comments Comment[] } model Comment { id Int @id @default(autoincrement()) text String postId Int post Post @relation(fields: [postId], references: [id]) }댓글 text가 ‘interesting’인 항목을 기준으로 게시글을 거르는 케이스를 가정 ...

November 17, 2025

Prisma findUnique에서 where와 include 제대로 쓰기

개요 findUnique로 단일 레코드 조회하면서 관련된 데이터까지 한 번에 가져오고 싶을 때 where와 include를 어떻게 조합해야 하는지 정리함 관계 필터링을 where에 넣을 수 있는지, include에서 필터가 가능한지 헷갈리기 쉬운 지점 정리 핵심 개념 findUnique는 유니크 키로 정확히 하나의 레코드를 찾는 용도 findUnique의 where는 유니크 필드만 허용됨, 관계 필터나 일반 조건 결합 불가 include는 조회된 레코드에 대한 연관 레코드를 함께 가져오는 옵션 to-many 관계에 한해 include 내부에서 where 사용 가능, to-one 관계는 where 불가 where 사용 패턴 잘못된 예시 // findUnique에 관계 필터 결합 시도 → 타입 에러 // (User(1) → Post(N) → Metadata(1) 관계) await db.user.findUnique({ where: { id: userId, // 'posts'는 유니크 필드가 아니므로 'where'에서 관계 필터링 불가 posts: { some: { metadata: { editorEmail: email } } }, }, }); 올바른 최소 조건 await db.user.findUnique({ where: { id: userId }, // 'id'는 유니크 필드 }); 관계 조건이 필요하면 findFirst 또는 findMany 사용 // 'findUnique'가 아닌 'findFirst'를 사용하면 // 'where'에 관계 필터를 포함할 수 있음 await db.user.findFirst({ where: { id: userId, posts: { some: { metadata: { editorEmail: email } } }, }, });요약하면 findUnique에는 유니크 조건만, 관계 기반 필터는 findFirst 또는 findMany로 처리함 ...

November 12, 2025

Prisma cursor 기반 페이지네이션 동작 원리와 skip: 1의 의미

개요 Prisma에서 cursor는 특정 레코드 지점부터 결과를 읽기 시작하는 기준점으로 동작함 skip: 1은 해당 cursor 레코드를 결과에서 제외하기 위한 옵션으로, 페이지 간 중복을 제거하는 데 사용함 핵심 동작 cursor는 그 지점부터 시작 await prisma.user.findMany({ cursor: { id: 100 }, take: 5, orderBy: { id: "asc" }, }); // 결과: 100부터 시작해 5개 반환 skip: 1은 cursor에 해당하는 레코드를 건너뜀 await prisma.user.findMany({ cursor: { id: 100 }, skip: 1, take: 5, orderBy: { id: "asc" }, }); // 결과: 101부터 5개 반환 예시로 보는 차이 데이터가 아래와 같다고 가정 ...

October 29, 2025