728x90
반응형

Backend 103

NestJS 다국어(i18n) 심화 적용기: 동적 변수 바인딩과 구조 리팩토링

[지난 글: NestJS 다국어(i18n) 적용기 - 에러부터 스케줄러까지]에서는 NestJS 프로젝트 전반에 다국어 처리 구조를 어떻게 설계하고 적용했는지 다루었습니다. 하지만 실무는 항상 기본 설정만으로 끝나지 않죠. 😅사용자의 이름이 포함된 알림을 보내거나, 날씨 API처럼 외부 데이터를 가공해야 할 때, 그리고 전역 필터에서 예상치 못한 버그를 마주했을 때 등 생각보다 디테일하게 챙겨야 할 부분들이 많았습니다. 오늘은 1편에 이어, 실제 서비스를 운영하며 겪었던 다국어 처리 관련 심화 적용 사례와 리팩토링 경험을 공유해보려고 합니다.1. 동적 값 보간(Interpolation): 메시지에 변하는 값 끼워넣기단순히 "안녕하세요"를 "Hello"로 번역하는 건 쉽습니다.하지만 실무에서는 가계부 예산..

Backend/NestJs 2026.05.23

NestJS 다국어(i18n) 적용기: 에러부터 스케줄러까지

글로벌 타겟의 서비스를 개발하다 보면 필수적으로 마주치는 과제가 바로 다국어(i18n) 처리입니다. 단순히 화면의 텍스트를 번역하는 것을 넘어, 백엔드에서는 API 에러 메시지, Validation 검증 결과, 심지어 HTTP 요청이 없는 스케줄러의 푸시 알림까지 상황에 맞게 언어를 변환해서 내려주어야 하죠. 저도 최근 프로젝트에서 다국어 처리를 구현하며 "어떻게 하면 비즈니스 로직(Service)에서 언어 설정에 대한 의존성을 줄일 수 있을까?"를 치열하게 고민했습니다.오늘은 제가 프로젝트에서 적용해 본 NestJS 기반의 단계별 다국어 처리 아키텍처를 공유하려고 해요.1. 언어 감지: 클라이언트의 언어는 어떻게 알까?가장 기본이 되는 설정입니다. 클라이언트(웹/앱)가 API를 호출할 때 자신이 원하는..

Backend/NestJs 2026.05.23

[Spring] 화이트리스트(Whitelist)를 활용한 XSS 공격 철벽 방어하기

XSS란? XSS와 CSRF 개념 및 차이점 정리 XSS와 CSRF 차이점 정리신입 시절, 기술 면접을 준비하거나 보안 관련 문서를 읽을 때마다 항상 헷갈리던 두 단어가 있었습니다.바로 XSS와 CSRF입니다.둘 다 웹 해킹 기법이라는 건 알겠는데, 막상 "정확히 뭐가 달라?"라show5116.tistory.com 웹 애플리케이션을 개발할 때 빼놓을 수 없는 보안 위협 중 하나가 바로 XSS(Cross-Site Scripting)입니다.악의적인 사용자가 웹 페이지에 악성 스크립트를 삽입해 다른 사용자의 정보를 탈취하거나 비정상적인 동작을 유발하는 공격이죠. XSS를 막기 위해 같은 위험한 태그를 막는 블랙리스트(Blacklist) 방식을 종종 사용하지만, 우회 기법이 끊임없이 발전하기 때문에 완벽한 방..

Backend/Spring 2026.04.02

NestJS XSS 방어: sanitize-html과 DTO Transform으로 자동화하기

게시판이나 공지사항 기능을 만들다 보면, 사용자가 작성한 HTML 태그를 그대로 받아 저장해야 하는 경우가 생깁니다.이때 무방비하게 데이터를 받으면 XSS(교차 사이트 스크립팅) 공격의 표적이 되기 딱 좋은데요.저 역시 최근 프로젝트에서 이 문제를 해결하기 위해 고민을 거듭했고, 오늘은 그 해결 과정을 여러분과 공유하려고 해요.XSS 방어, 왜 반드시 필요할까요?악의적인 사용자가 태그나 onload 같은 이벤트 핸들러를 섞어 보내면, 다른 사용자가 해당 게시글을 열었을 때 악성 스크립트가 실행되는 끔찍한 일이 발생할 수 있습니다.💡 참고: XSS의 구체적인 개념과 원리, 그리고 왜 반드시 막아야 하는지에 대해서는 제가 이전에 자세히 정리해 둔 글이 있어요. 혹시 개념 정리가 먼저 필요하시다면 아래 링..

Backend/NestJs 2026.03.22

자바 String vs StringBuilder 비교: 불변성과 JDK 버전별 동작 원리

자바를 처음 배울 때 "String은 불변(Immutable) 객체라 + 연산자로 문자열을 더하면 메모리 낭비가 심하니 무조건 StringBuilder를 쓰세요!"라는 말을 많이 들어보셨을 거예요.저 역시 신입 시절에는 이 규칙에 강박을 가져서, 가벼운 문자열 두세 개를 합칠 때도 코드를 길게 늘여가며 StringBuilder를 썼던 기억이 납니다. 하지만 실무에서 코드를 까보고 여러 레퍼런스를 찾아보면서, 자바 컴파일러가 JDK 버전에 따라 이 + 연산을 꽤 똑똑하게 최적화해주고 있다는 사실을 알게 되었어요.오늘은 String과 StringBuilder의 근본적인 차이를 짚어보고, JDK 버전별로 문자열 더하기 연산이 내부적으로 어떻게 동작하는지 저의 경험과 함께 공유해 드릴게요!1. String과 S..

Backend/Java 2026.03.19

[Spring] P6Spy로 일관된 쿼리 로깅 환경 구축하기

실무에서 프로젝트를 진행하다 보면 JPA만 단독으로 쓰기보다는, 복잡한 통계 쿼리를 위해 QueryDSL을 섞어 쓰거나 레거시 코드로 인해 MyBatis, JdbcTemplate 등을 한 서비스 안에서 혼용하는 경우가 꽤 많죠.저도 이런 환경에서 개발하다 보니, 각 기술마다 쿼리가 찍히는 로깅 포맷이 달라서 디버깅할 때마다 로그 읽기가 너무 고통스럽더라고요.그래서 이 파편화된 로깅 방식을 한 번에 통일해서 잡아주는 P6Spy를 도입하게 되었고, 그 과정과 실무 적용 팁을 공유해 보려고 합니다.1. 왜 P6Spy를 도입해야 할까요?하나의 프로젝트에서 JPA, MyBatis, JdbcTemplate 등을 함께 사용하면 어떤 문제가 발생할까요?JPA(Hibernate): spring.jpa.show-sql=t..

Backend/Spring 2026.03.06

[Spring] 커스텀 어노테이션 4편: Lombok은 어떻게 코드를 만들어낼까? (AST 조작)

어느덧 커스텀 어노테이션 시리즈의 마지막 편입니다!1편의 기본 개념을 시작으로, 2편에서는 런타임에 메소드를 가로채는 AOP를, 3편에서는 클래스 정보를 동적으로 읽어오는 Reflection을 다루었죠. 오늘은 어노테이션 활용의 끝판왕이자, 우리가 숨 쉬듯 사용하고 있는 Lombok(@Getter, @Setter)의 동작 원리인 AST(Abstract Syntax Tree) 조작에 대해 이야기해 보려 합니다. 솔직히 말씀드리면, 4년 차인 저도 실무에서 AST를 직접 조작하는 코드를 구현하지는 않습니다.유지보수도 까다롭고 구현 난이도도 너무 높기 때문이죠.하지만 우리가 매일 쓰는 도구의 원리를 아는 것과 모르는 것은 문제 해결 능력에서 큰 차이를 만듭니다.가벼운 마음으로 "아, 롬복이 이렇게 일하는구나!..

Backend/Spring 2026.03.04

[Spring] 커스텀 어노테이션 3편: 리플렉션(Reflection)으로 메일 폼 자동 생성기 만들기

지난 2편에서는 AOP를 이용해 메소드 앞뒤에 공통 로직을 끼워 넣는 방법을 배웠습니다.하지만 가끔은 메소드 호출을 가로채는 것만으로는 부족할 때가 있습니다."객체 안에 어떤 필드가 있는지 런타임에 다 훑어서, 특정 어노테이션이 붙은 값들만 뽑아낼 수 없을까?" 하는 고민이죠. 저도 실무에서 메일 발송 기능을 구현할 때 비슷한 고민을 했습니다.메일 폼에 들어갈 데이터가 매번 달라지는데, 그때마다 수동으로 Map에 담아주는 게 너무 번거로웠거든요. 오늘은 이 문제를 리플렉션(Reflection)으로 우아하게 해결한 경험을 공유해 드릴게요.1. 리플렉션(Reflection)이란?리플렉션은 구체적인 클래스 타입을 알지 못해도 컴파일된 바이트 코드를 통해 클래스의 메소드, 필드, 어노테이션 정보를 들여다보고 조..

Backend/Spring 2026.03.03

[Spring] 커스텀 어노테이션 2편: AOP로 실행 시간 측정 기능 만들어보기

지난 포스팅에서는 어노테이션의 개념과 동작 원리 3가지를 알아봤습니다.오늘은 그중 실무에서 가장 빈번하게 사용되는 AOP(Aspect Oriented Programming)를 이용해, 우리가 만든 어노테이션에 실제 기능을 불어넣어 보려고 합니다."이 메소드 수행 시간이 얼마나 걸리지?"라는 질문을 받을 때마다 모든 메소드 시작과 끝에 로그를 찍고 계셨나요?이제 @TrackTime 하나로 그 고민을 끝내보겠습니다.1. 왜 AOP인가요?지난 글에서 언급했듯, 어노테이션 자체는 이름표일 뿐입니다.누군가는 이 이름표를 보고 "어? 이거 실행 시간 재야 하네?"라고 판단한 뒤 로직을 끼워 넣어야 하죠.Spring AOP는 타겟 메소드(Target)가 실행될 때 이를 가로채서(Intercept) 앞뒤로 공통 로직을..

Backend/Spring 2026.03.01

[Spring] 커스텀 어노테이션 1편: 어노테이션의 기본 개념과 3가지 동작 원리 이

Spring으로 개발하다 보면 수많은 어노테이션을 만납니다.코드 위에 @ 하나만 붙였을 뿐인데 트랜잭션이 걸리고, JSON으로 변환되는 모습을 보면 가끔은 '마법 같다'는 생각이 들기도 하죠.저도 연차가 쌓이면서 반복되는 로직을 줄이고 싶을 때 "이걸 내가 직접 만들어서 자동화할 순 없을까?"**라는 고민을 하게 되었습니다.오늘부터 시작할 시리즈는 그 마법의 정체를 파악하고, 우리만의 지팡이(커스텀 어노테이션)를 만드는 과정을 담았습니다.그 첫 번째 시간으로 어노테이션의 본질과 이를 동작하게 만드는 3가지 방법에 대해 깊이 있게 다뤄보겠습니다.1. 어노테이션(Annotation)이란 무엇인가?사전적 의미로 어노테이션은 '주석'입니다.하지만 우리가 코드에 쓰는 // 주석과는 결이 다릅니다.일반 주석이 개발..

Backend/Spring 2026.02.27