728x90

2025/06 8

[Gin] GORM에서 CQRS 아키텍처 구현해보기

읽기와 쓰기를 분리하여 유지보수성과 성능을 챙기자!✅ CQRS란?CQRS(Command Query Responsibility Segregation)는 **쓰기(Command)**와 읽기(Query) 책임을 서로 다른 모델 또는 레이어로 분리하는 아키텍처 패턴입니다.기존 CRUD는 하나의 모델이 모든 작업을 처리CQRS는 복잡한 시스템에서 명확하고 유연한 구조 제공 📦 GORM에서 CQRS를 구현하는 이유이점 설명책임 분리읽기/쓰기 로직 분리로 유지보수 용이성능 최적화읽기에서 복잡한 JOIN 최소화 가능테스트 용이Command/Query 각각 테스트 가능확장성Read-Replica, Kafka 등 확장 용이 📐 디렉토리 구조 예시/internal /user - command_repositor..

개발/Go 2025.06.18

[Gin] GORM + Redis 캐싱 전략 - DB 부하 줄이는 실전 캐싱

DB 부하를 Redis로 덜어주는 실전 패턴 ✅ 왜 캐싱이 중요한가?- 자주 조회되는 데이터를 매번 DB에서 가져오면 성능에 큰 부담 - GORM만 사용하면 매 요청마다 쿼리 발생 - Redis를 캐시로 두면 응답 속도 향상 + DB 부하 감소 🧱 기본 구조 Client → Gin → Service ├── Redis 캐시 hit → 바로 응답 └── miss → GORM → DB → 캐시 저장 → 응답 🧪 실습 전제 - Gin + GORM + Redis 사용 - User 모델 조회 예시 - Redis는 go-redis 사용 1. Redis 설정import ( "github.com/redis/go-redis/v9" "..

개발/Go 2025.06.16

[Gin] GORM 디버깅 & 에러 핸들링 완전정복

에러 무시하다가 큰일난다 - 실전에서 통하는 GORM 디버깅 & 예외 처리 전략 ✅ 목차GORM 에러 핸들링의 기본 구조 RowsAffected로 실패 원인 파악하기 특정 에러 구분하기 (errors.Is, errors.As) 로그 레벨 조절로 SQL 추적하기 실전 예제: 유저 존재 확인 후 조건부 저장 디버깅 꿀팁 & 실수 피하기 1. GORM 에러 핸들링 기본 구조 GORM의 대부분 메서드는 .Error 필드에 에러를 담는다. user := User{}err := db.First(&user, 1).Errorif err != nil { // 에러 처리} 하지만 이렇게만 쓰면 에러 원인을 정확히 알기 어렵다. 2. RowsAffected로 레코드 유무 판단하기쿼리는 성..

개발/Go 2025.06.13

[Gin] GORM으로 단위 테스트 잘하는 법 - 테스트 환경 구성부터 Mock까지

실무 백엔드에서는 기능 구현만큼 중요한 게 테스트다. 특히 DB를 다루는 GORM에서는 테스트 코드 작성이 까다로울 수 있지만, 구조만 잘 잡으면 생산성도, 안정성도 높아진다. ✅ 목차 - GORM 테스트, 왜 어려울까? - 테스트 환경 구성 전략 - SQLite in-memory DB - 트랜잭션 롤백 - 인터페이스 분리로 Mocking 가능하게 만들기 - gorm.io/datatypes, faker로 더 현실적인 테스트 - 실전 테스트 예제 정리 1. GORM 테스트, 왜 어려울까? GORM은 DB 연결을 전제로 하기 때문에, 테스트 시 다음 이슈가 생긴다: - 실제 DB를 연결하면 테스트 데이터 관리가 어렵다. - 트랜잭션 롤백 없이 돌리면 더티 데이터가 남는다. - GORM 객체가..

개발/Go 2025.06.11

[Gin] GORM에서 안전한 쿼리 작성법 - SQL 인젝션 방지와 Named Parameter 전략

SQL 인젝션은 여전히 실무에서 가장 빈번하게 발생하는 보안 위협 중 하나다. Go 백엔드에서 ORM으로 GORM을 쓴다고 해도, 안전하지 않은 쿼리 작성은 여전히 인젝션 공격의 여지를 남긴다. 이번 글에서는 다음 내용을 상세히 다룬다. ✅ 목차 - SQL 인젝션이란? - GORM에서 발생할 수 있는 인젝션 사례 - 안전한 쿼리 작성법 - 바인딩 방식 - Named Parameter 전략 - Struct 기반 조건 - Raw SQL 시 주의할 점 - 실전 방어 전략 요약 1. SQL 인젝션이란?SQL 인젝션(SQL Injection)이란, 쿼리문에 사용자 입력값이 그대로 삽입되면서 악의적인 SQL이 실행되는 공격이다. 예를 들어 아래처럼 문자열을 직접 연결하면:db.Exec("DELETE ..

개발/Go 2025.06.09

[Gin] GORM 마이그레이션 전략 - 자동 vs 수동 관리, 안전하게 스키마 관리하기

Go로 백엔드를 개발할 때 GORM의 마이그레이션 기능은 정말 편리하다. 하지만 무턱대고 자동 마이그레이션만 쓰다 보면 데이터 유실, 인덱스 충돌, 운영 장애까지 발생할 수 있다. 이번 글에서는 GORM에서 자동 마이그레이션과 수동 마이그레이션을 언제 어떻게 써야 하는지, 실전 전략을 정리해보자. 📌 목차 - GORM AutoMigrate 기본 사용법 - 자동 마이그레이션의 한계와 리스크 - 수동 마이그레이션 관리 전략 - 실전 추천 전략 (개발/운영 구분) - 마무리 요약 1. GORM AutoMigrate 기본 사용법GORM은 AutoMigrate()로 테이블을 생성하고 컬럼을 자동으로 추가해준다.db.AutoMigrate(&User{}, &Post{}) - 존재하지 않는 테이블이면 생..

개발/Go 2025.06.06

[Gin] GORM 성능 최적화 팁 - Preload, Select, Index 전략까지!

GORM은 Go에서 가장 널리 쓰이는 ORM이지만, 아무 설정 없이 쓰다 보면 쿼리가 많아지고 성능이 떨어질 수 있다. 이번 글에서는 GORM에서 성능을 높이기 위한 Preload, Select, Index 전략들을 정리해보자. 📌 목차 - N+1 문제와 Preload - 필요한 컬럼만 조회하기 — Select - Index 전략 - 정리 1. N+1 문제와 Preload 🤔 N+1 문제란? 예를 들어 게시글(Post)과 작성자(User) 관계가 있을 때, 게시글 10개를 조회하면서 각 게시글의 작성자를 따로 조회하면 1 + N 쿼리가 발생한다. type Post struct { ID uint Title string UserID uint User User}// 잘못된 예..

개발/Go 2025.06.04

[Javascript] 함수가 기억을 한다고? 자바스크립트 클로저 쉽게 설명해봄

JS의 클로저에 대해서 알아보자 ✅ 한 줄 정의클로저는 함수가 자신이 선언될 때의 스코프(변수 환경)를 기억하고, 그 외부 함수가 종료된 이후에도 그 변수들에 접근할 수 있는 함수. 📌 기본 예시 function outer() { let count = 0; // outer의 지역 변수 return function inner() { count++; console.log(count); };}const counter = outer(); // outer는 실행되고 종료됨, 하지만 inner는 리턴됨counter(); // 1counter(); // 2counter(); // 3 outer() 실행 시, count 변수와 함께 inner() 함수가 생성됨. inner()는 co..

728x90