2025년 10월부터 12월까지, 저는 WegglePlus라는 이름으로 정말 많은 서비스를 만들어봤습니다.가장 큰 기조는 단순했습니다.“바이브코딩으로 일단 빠르게 MVP를 만들자.”실제로 여러 개의 서비스를 만들었고, 개발적으로도 많이 배웠습니다.하지만 2025년 12월이 되었을 때, 저는 한 가지 생각이 들었습니다.이 방식으로는 더 이상 서비스를 만들면 안 되겠다. 왜 실패했다고 느꼈는가돌아보니 문제는 명확했습니다.1. 매일 개발 방향이 바뀐다목표가 없었습니다.아이디어는 있었지만 “무엇을 이루려는 서비스인가”는 없었습니다.결국 매일 새 프로젝트를 시작하는 기분이었습니다.2. 작은 것부터 시작하지 않았다원래는 이렇게 해야 합니다.티끌 모아 태산 하지만 저는 반대로 하고 있었습니다.태산 모아 티끌 처음부터..
전체 글
개발, PO, PM, 기획과 관련된 서비스 관련 업무에 관심이 있습니다. 또한 성장,교육과 관련된 주제에 대해서도 관심이 많습니다. 티타임을 좋아하는 사람으로써, 혹시 티타임에 관심이 있으신 분은 ksy90101@gmail.com로 메일 보내주시면 감사하겠습니다 :) 과제를 제공해주고 피드백을 주는 서비스를 오픈하였습니다. 관심있으신 분들은 https://jobskill.notion.site/ 해당 사이트를 참고해주세요.GitHub Actions에서 N+1 쿼리를 자동으로 감지하고 PR에 코멘트 달기들어가며N+1 쿼리는 ORM을 사용하는 애플리케이션에서 가장 흔하게 발생하는 성능 문제입니다. 개발 환경에서는 데이터가 적어 눈에 띄지 않지만, 프로덕션에서는 심각한 성능 저하를 일으킵니다.이 글에서는 GitHub Actions CI 파이프라인에서 N+1 쿼리를 자동으로 감지하고, 코드 라인에 직접 리뷰 코멘트를 다는 방법을 소개합니다.목표PR에서 변경된 테스트 파일에서 발생한 N+1만 감지N+1이 발생한 정확한 테스트 위치에 리뷰 코멘트N+1이 수정되면 자동으로 코멘트 삭제rswag run_test! 실행 시에만 N+1 감지 활성화기존 접근 방식의 한계Prosopite만 사용할 때Prosopite는 N+1 쿼리를 감지하는 ..
들어가며WegglePlus 팀은 블로그 콘텐츠를 통한 검색 유입 확대와 서비스 성장을 목표로 새로운 마케팅 프로젝트를 시작했습니다. 이 프로젝트의 핵심은 **SEO(검색엔진 최적화)**를 통해 안정적인 트래픽을 확보하고, 이를 WegglePlus 서비스 유입으로 연결하는 것입니다.오늘은 SEO의 기본 중 기본, Sitemap과 Robots.txt 구현 과정을 공유합니다.Sitemap과 Robots.txt가 왜 중요할까?Sitemap.xmlSitemap은 웹사이트의 페이지 목록을 검색엔진에 알려주는 XML 파일입니다. 검색엔진 크롤러가 사이트 구조를 빠르게 파악하고, 새로운 콘텐츠를 효율적으로 색인할 수 있도록 도와줍니다. 2026-01-10 weekly 0.8Robots.txtRobots.txt..
문제 상황프로덕션 환경에서 특정 API의 메모리 사용량이 비정상적으로 높다는 알림을 받았습니다. 요청이 들어올 때마다 메모리가 계속 증가하고, GC(Garbage Collection)가 제대로 동작하지 않는 것처럼 보였습니다.1단계: 메모리 프로파일링 미들웨어 구현먼저 문제를 정량적으로 측정하기 위해 메모리 프로파일링 미들웨어를 구현했습니다.# app/core/memory_profiler.pyimport gcimport tracemallocfrom collections.abc import Callableimport psutilfrom starlette.middleware.base import BaseHTTPMiddlewarefrom starlette.requests import Requestfrom st..
들어가며블로그를 운영하다 보면 RSS 피드는 필수 기능 중 하나입니다. Feedly, Inoreader 같은 RSS 리더를 통해 구독자들이 새 글을 쉽게 받아볼 수 있기 때문이죠. 이번 글에서는 Spring Boot와 Kotlin 환경에서 다국어(한국어/영어)를 지원하는 RSS 2.0 피드를 구현한 경험을 공유합니다.기술 스택Spring Boot 3.5.6Kotlin 1.9.25Rome 2.1.0 (RSS/Atom 피드 라이브러리)Rome 라이브러리 선택 이유RSS 피드를 구현하는 방법은 여러 가지가 있습니다:방법 장점 단점직접 XML 생성의존성 없음유지보수 어려움, 버그 가능성Rome 라이브러리검증된 라이브러리, Spring 통합 용이추가 의존성JAXBJava 표준설정 복잡Rome은 RSS/Atom 피..
웹과 앱을 모두 고려한 현실적인 인증 전략 (fetch 기반 구현)로그인 이후 토큰을 어디에 저장할 것인가는 단순한 구현 문제가 아닙니다.이 선택은 보안 모델, 사용자 경험(UX), 그리고 웹과 앱을 함께 운영할 수 있는지 여부까지 결정합니다.이번 글에서는 우리가 최종적으로 선택한 인증 구조인 Refresh Token은 HttpOnly 쿠키, Access Token은 메모리 라는 전략을, 프론트엔드(fetch 기반) 구현과 앱(WebView) 대응 관점까지 포함해 정리합니다.1. 왜 다시 토큰 저장 전략을 고민했을까?전통적으로 많이 사용되던 방식은 다음과 같습니다.Access Token → 쿠키Refresh Token → 쿠키구현은 간단하지만, 실무에서는 다음과 같은 문제가 반복해서 드러났습니다.Acce..
운영 중인 서비스에서 특정 조회 API가 간헐적으로 실패하며 다음과 같은 MySQL 에러가 발생했습니다.Out of sort memory, consider increasing server sort buffer size처음에는 단순한 쿼리 성능 이슈로 보였지만, 실제 원인은 MySQL의 정렬(filesort) 과정에서 발생한 메모리 부족(OOSM) 이었습니다.이번 글에서는 OOSM이 무엇인지, 왜 발생하는지, 그리고 우리가 실제로 어떻게 해결했는지를 공유합니다.OOSM이란 무엇인가?OOSM(Out Of Sort Memory) 은 MySQL이 ORDER BY, GROUP BY 등을 처리하는 과정에서 정렬을 위한 메모리(sort buffer)가 부족할 때 발생하는 에러입니다.MySQL은 다음 두 가지 방식으로..
서론우리 팀은 여러 서비스를 하나의 백엔드 서버와 하나의 DB에서 모두 관리하고 있습니다.그러다보니 Category 모델의 개념의 분류화, 유형화 등을 쓸일이 많습니다.이제 그부분을 두가지 방법으로 관리할수 있을것입니다.단순 String 컬럼을 추가한다.각각의 모델에 따라 Cateogry 모델을 만들어서 관리한다.이러다보니, 현재 팀의 모토인 빠르게 서비스를 개발하고 사용자에게 가치를 주는 일을 주기 위해서 개발의 시간이 많이 드는것을 느꼈습니다.따라서 이번에 시간이 조금 들여도 공통 모델을 만들어서 관리할수 있도록 하는것을 목표로 하였습니다.해결하고자 하는 방안Category의 개념이 필요할때마다 Cateogry를 의미하는 모델을 새롭게 추가할 필요가 없어야 한다.서비스와 타입에 따라 카테고리가 관리되..
a.b.c 조전까지만 해도 무심코 쓰던 코드입니다. A모델에 B가 있으니, 체인으로 c를 꺼내 쓰는 게 자연스럽게 느껴졌죠. 하지만 이 패턴은 Law of Demeter—최소 지식 원칙—을 정면으로 위배합니다. “내 옆집 문을 열어달라고 내 친구에게 부탁하지 말라”는 말처럼, 객체는 자신과 직접 관련된 이웃에게만 말을 걸어야 합니다. 그렇지 않으면 내부 구조가 외부에 노출돼 결합도가 치솟고, 작은 구조 변경이 연쇄 폭발로 이어집니다.이번 글에서는 운영 중인 rails 프로젝트를 예시로, Law of Demeter를 Rails에서 어떻게 지키고 있는지, delegate를 활용하면 어떤 장단점까지 정리해 봅니다.1. 문제는 어디서 시작됐나?A는 B과 1:1 관계를 맺고 있습니다. 외부에서 B의 c를 알고 싶..
Locale 공통화는 다국어 서비스를 운영할 때 필수적인 인프라로, 모든 API가 동일한 언어 판별 규칙을 따르도록 일원화한 작업입니다. 이를 통해 코드 중복을 줄이고 서비스 전반의 언어 일관성을 확보했습니다.왜 Locale이 필요한가?저희 서비스는 다국어(한국어, 영어) 를 지원합니다.동적 데이터는 하나의 DB 컬럼을 JSON 형태로 관리하고 있습니다.예를 들어 블로그 글이 있다고 해봅시다.글의 제목은 한국어와 영어를 모두 지원해야 하므로 모델은 이렇게 정의됩니다.class Post { title: {ko: "Spring Locale 공통화 여정", en: "The Journey to Unify Locale Management in Spring" }}이제 이 데이터를 가지고 DTO에서 lang을 받아..