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

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

December 19, 2025

개발자 커리어에서 마주치는 임포스터와 우월감 증후군 정리

개요 개발 현장은 기술 변화가 빠르고 학습 범위가 넓음 이 환경에서 임포스터 증후군과 우월감 증후군은 자주 관찰되는 심리 상태이며, 같은 사람이 커리어 단계에 따라 두 상태를 오가기도 함 핵심 개념과 개발자 맥락에서의 징후, 발생 배경, 성장 곡선 상의 위치, 건강한 마인드셋을 정리함 핵심 개념 임포스터 증후군 스스로 실력을 과소평가하고 운이나 타인의 공 덕분에 현재 위치에 있다고 여기는 불안 심리 들킬 것 같은 두려움이 동반됨 개발자 맥락에서 보이는 징후 구글링 의존을 부끄러워하며 자신을 가짜 개발자로 규정함 성과를 팀 운이나 외부 요인으로만 해석함 질문을 회피하고 비난을 두려워해 홀로 고립됨 더 알수록 모르는 영역이 보이며 시니어가 되어도 불안 증가 우월감 증후군 ...

December 18, 2025

date-fns로 자바스크립트 날짜·시간 처리 23가지 실전 패턴

개요 자바스크립트에서 날짜·시간을 다루는 일은 사소해 보이지만 버그가 가장 잦은 영역 중 하나임 day.js, moment.js, luxon 등 대안 존재하나 date-fns는 모듈화, 작은 크기, 불변성 중심 설계로 프런트엔드와 백엔드 모두에 적합함 아래는 date-fns와 date-fns-tz를 활용해 바로 써먹을 수 있는 23가지 패턴 정리 핵심 개념 Date 객체는 타임존이 아닌 UTC 타임스탬프를 보유하는 값이라는 점이 핵심 date-fns 함수는 대부분 불변 동작, 인자로 받은 Date를 변경하지 않음 포맷팅은 format, 상대 표기는 formatDistance 계열, 구간 계산은 differenceIn*, intervalToDuration 등 사용 파싱은 parseISO 또는 parse로 명시적 포맷 지정 권장 타임존 변환은 date-fns-tz의 utcToZonedTime, zonedTimeToUtc, formatInTimeZone 사용 실전 패턴 현재 날짜와 시간 가져오기 const now = new Date() 특정 날짜·시간 설정 import { setMinutes, setHours } from 'date-fns' const specific = setHours(setMinutes(new Date(), 30), 17) // 17:30 날짜 포맷팅 import { format } from 'date-fns' const ymd = format(new Date(), 'yyyy-MM-dd') 기간 더하기·빼기 import { addDays, subMonths } from 'date-fns' const inAWeek = addDays(new Date(), 7) const aMonthAgo = subMonths(new Date(), 1) 특정 요일까지 남은 일수 import { nextDay, differenceInDays } from 'date-fns' const nextMon = nextDay(new Date(), 1) // 0 일요일, 1 월요일 const d = differenceInDays(nextMon, new Date()) 두 날짜 차이 계산 import { differenceInDays } from 'date-fns' const diff = differenceInDays(new Date(2023, 11, 31), new Date(2023, 0, 1)) 동일한 날짜 비교 import { isSameDay } from 'date-fns' const same = isSameDay(new Date(2023, 0, 1), new Date('2023-01-01T05:00:00Z')) 윤년 확인 import { isLeapYear } from 'date-fns' const isLeap = isLeapYear(new Date(2024, 0, 1)) 날짜 유효성 검사 import { isValid } from 'date-fns' const ok = isValid(new Date('2023-02-30')) // false 로컬과 특정 타임존 간 변환 import { utcToZonedTime, zonedTimeToUtc, formatInTimeZone } from 'date-fns-tz' const tz = 'America/New_York' const utc = zonedTimeToUtc(new Date(), tz) const inNY = utcToZonedTime(new Date(), tz) const shown = formatInTimeZone(new Date(), tz, 'yyyy-MM-dd HH:mm:ssXXX') 문자열 파싱 import { parseISO, parse } from 'date-fns' const a = parseISO('2023-01-01') const b = parse('01/02/2023 17:30', 'MM/dd/yyyy HH:mm', new Date()) 상대 시간 표현 import { formatDistanceToNow } from 'date-fns' import { ko } from 'date-fns/locale' const rel = formatDistanceToNow(new Date(Date.now() - 3 * 24 * 60 * 60 * 1000), { addSuffix: true, locale: ko }) 과거·미래 판별 import { isPast, isFuture } from 'date-fns' const past = isPast(new Date('2023-01-01')) const future = isFuture(new Date(Date.now() + 60_000)) 특정 기간의 날짜 배열 생성 루프 대신 eachDayOfInterval 사용 권장 ...

December 17, 2025

Node.js 모듈 시스템 정리: CommonJS와 ESM의 차이, 선택 기준, 상호 운용

개요 Node.js에서 CommonJS(CJS)와 ESM(ES Modules)은 공존 상태이며, 신규 프로젝트는 ESM으로 전환되는 추세임. 두 시스템의 차이를 이해하면 번들 크기, 로딩 성능, 정적 분석, 생태계 호환에서 불필요한 시행착오 감소 가능 배경 2009년 Node.js는 표준 모듈 시스템이 없던 시기라 CommonJS 채택 2015년 ES6에서 ESM이 언어 차원의 공식 표준으로 확정 2020년대 들어 Node.js가 ESM을 정식 지원, 브라우저와 규약 수렴 진행 CommonJS 요약 // export module.exports = { foo: 1 } exports.bar = 2 // import const { foo, bar } = require('./utils')특성 ...

December 16, 2025

이더리움 가스 이해하기: Gas Limit, Gas Price, EIP-1559 정리

개요 EVM 트랜잭션 수수료 모델은 자동차 연료 비유가 직관적임 Gas는 연료, 트랜잭션 수행은 목적지까지 주행이라는 맥락으로 이해하면 됨 핵심은 두 파라미터, Gas Limit와 Gas Price이며 EIP-1559 이후에는 Base Fee와 Priority Fee로 세분됨 핵심 개념 Gas Limit 이 트랜잭션이 최대 얼마만큼의 연산을 사용할 수 있는지에 대한 상한 단순 ETH 송금은 21,000 가스 고정값 수준 컨트랙트 실행은 로직 복잡도, 저장소 접근, 반복 등에 비례해 증가 사용하지 않은 가스는 환불, 부족하면 Out of Gas로 실패 후 사용한 가스 비용만큼 청구 Gas Price ...

December 15, 2025

MySQL 클러스터드 인덱스와 논클러스터드 인덱스 이해와 선택 기준

개요 테이블 검색 성능을 끌어올리는 1차 수단은 인덱스 구축임 인덱스는 단일 컬럼 또는 다중 컬럼 기준으로 생성 가능하며, 다음과 같은 기본 생성 규칙이 작동함 Primary Key 지정 시 클러스터드 인덱스 생성 Unique 제약은 보조 인덱스(논클러스터드 인덱스, InnoDB에선 Secondary Index)로 생성 MySQL의 InnoDB는 B+Tree 기반 인덱스를 사용하며, 데이터 저장 구조와 접근 패턴이 인덱스 유형별로 상이함 핵심 개념 정리 클러스터드 인덱스 테이블 데이터가 인덱스 키 순서로 정리되는 구조 테이블당 하나만 존재 리프 노드가 실제 레코드(전체 컬럼)를 보유 InnoDB에서 Primary Key가 곧 클러스터드 인덱스가 됨 PK가 없으면 첫 번째 유니크 not null 인덱스를 사용, 그것도 없으면 내부적으로 보이지 않는 6바이트 Row ID를 생성해 클러스터링 키로 사용 논클러스터드 인덱스(보조 인덱스, Secondary Index) ...

December 14, 2025

사이드카 패턴 이해와 도입 판단 가이드: 마이크로서비스·쿠버네티스에서의 활용

개념과 배경 마이크로서비스로 분산이 심화되면 로깅, 모니터링, 보안, 네트워킹 같은 공통 기능을 어디에 둘지 결정이 어려워짐 애플리케이션 코드에 공통 기능을 계속 끼워 넣으면 침투와 중복 증가, 배포와 버전 관리 복잡도 상승 사이드카 패턴은 공통 기능을 별도 컨테이너로 분리해 메인 서비스는 비즈니스 로직에 집중하게 하는 접근법 컨테이너 오케스트레이션 환경에서 일관된 운영 모델을 제공한다는 점이 실무적 장점 핵심 개념 사이드카 패턴의 구성 요소 메인 컨테이너: 비즈니스 로직 담당, 웹 서비스나 API 서버 등 사이드카 컨테이너: 횡단 관심사 처리, 로그 수집, 모니터링 에이전트, 프록시, 보안 검사 등 같은 파드 내 배치로 네트워크 네임스페이스와 볼륨 공유 가능, 표준 출력/공유 볼륨 등을 통해 데이터 연계 업데이트와 배포를 컨테이너 단위로 분리해 독립적 버전 관리 가능 동작 원리 하나의 파드에 메인 컨테이너와 사이드카 컨테이너를 함께 배치 ...

December 13, 2025

Node.js 글로벌 에러 핸들러 가이드

개념/배경 Node.js 프로세스 레벨에서 잡히지 않은 에러를 마지막으로 처리하는 안전망을 두는 목적 정리 애플리케이션 어디에서도 처리되지 못한 오류를 기록하고 종료 경로를 일관되게 관리하기 위함 프로덕션 환경에서 원인 파악과 사후 조치 자동화를 위한 최소 장치로 간주 핵심 이벤트 두 가지 이벤트가 글로벌 핸들러의 대상 uncaughtException try-catch로 포착되지 않은 동기 오류가 호출 스택 끝까지 전파될 때 발생 핸들러가 없으면 프로세스가 비정상 종료됨 // 동기 에러가 상위에서 잡히지 않은 경우 function boom() { throw new Error('폭발') } boom() unhandledRejection Promise가 reject되었으나 await 혹은 .catch로 처리되지 않은 경우 발생 Node.js 15+ 기본 동작은 핸들러가 없을 때 프로세스 종료 // reject가 소비되지 않은 경우 async function asyncBoom() { throw new Error('비동기 폭발') } asyncBoom()왜 글로벌 핸들러인가 코드 최상위에서 아무도 잡지 못한 에러에 대한 마지막 안전망 역할 ...

December 12, 2025

Kubernetes에서 Node.js Liveness와 Readiness Probe 설계 가이드

개요 Kubernetes 환경에서 Liveness Probe와 Readiness Probe는 애플리케이션 상태를 주기적으로 점검해 자동 복구와 트래픽 차단을 수행하는 안전 장치 역할 수행 Node.js는 싱글 스레드 기반으로 이벤트 루프 차단이나 메모리 누수 상황이 치명적이라 두 프로브의 설계가 안정성에 직접적인 영향 미침 핵심 차이 Liveness Probe의 질문은 너 살아있니, 실패 시 컨테이너 재시작 수행 Readiness Probe의 질문은 일할 준비 됐니, 실패 시 서비스 엔드포인트에서 제외해 트래픽 차단 수행 본질적 차이는 실패 시 K8s가 취하는 액션이며 재시작과 트래픽 제어로 구분됨 Node.js 맥락 Liveness Probe 대상 상황 이벤트 루프 블로킹으로 요청 처리 불가 상태 무한 루프 또는 데드락과 유사한 좀비 상태로 PID는 있으나 응답 불능 메모리 누수로 OOM 임박하여 응답 지연 또는 멈춤에 가까운 상태 Readiness Probe 대상 상황 프로세스는 떠 있으나 초기화 작업 진행 중인 상태 DB 연결 수립 중, 대용량 설정 로딩, 캐시 워밍업 등으로 실제 서비스 처리 불가 상태 유의점 Liveness는 가벼운 체크로 한정, 외부 의존성까지 포함 시 불필요한 재시작 유발 위험 Readiness는 실제 트래픽 처리 가능 여부를 반영해야 하며 의존성 준비 상태를 포함하는 편이 안전함 구현 스니펫 Node.js에서 Liveness는 최소한의 핑 수준으로, Readiness는 의존성 준비 여부를 반영하는 형태 권장 ...

December 11, 2025

JavaScript Array.prototype.flatMap 개념과 사용 예시

개념 flatMap은 각 요소를 매핑한 결과를 한 단계만 평탄화하는 배열 메서드 arr.map(fn).flat(1)과 동등 동작 콜백 시그니처 (value, index, array) 콜백이 배열을 반환하면 concat 후 depth 1 평탄화 더 깊은 중첩은 유지됨 희소 배열의 빈 슬롯은 평탄화 과정에서 제거됨 ES2019 이후 표준 지원 범위 넓음 예시 const arr = [1, 2, 3, 4] arr.flatMap(x => [x * 2]) // => [2, 4, 6, 8] arr.flatMap(x => [[x * 2]]) // => [[2], [4], [6], [8]] const s = ["it's Sunny in", "", "California"] s.flatMap(x => x.split(" ")) // => ["it's","Sunny","in","","California"] 주의와 팁 깊이 2 이상 평탄화 필요 시 flat(depth) 사용 또는 map + flat 조합 고려 콜백은 배열을 반환하는 패턴 권장, 스칼라를 섞으면 의도치 않은 구조 발생 가능 희소 배열 처리 시 구멍이 사라지는 특성 주의 성능상 불필요한 중첩 생성은 피하고 필요한 경우에만 flatMap 사용 권장 참고자료 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap

December 10, 2025