전체 글52 오버페칭이 싫어 GraphQL로 갔다가 만난 것들 오버페칭이 싫어 GraphQL로 갔다가 만난 것들을, 실제 전환을 겪으며 알게 된 장단점 위주로 정리한 글입니다. REST에서 반복되던 오버페칭과 언더페칭지금도 기억나는 화면이 하나 있습니다. 2년 전 사내 커머스 앱의 상품 상세 페이지였는데요, 이 화면 하나를 그리려고 클라이언트가 REST 엔드포인트를 세 번이나 호출하고 있었습니다. 상품 기본 정보를 받으려 /products/{id} 를 부르고, 리뷰 요약을 받으려 /products/{id}/reviews 를 부르고, 판매자 배지를 받으려 다시 /sellers/{id} 를 부르는 식이었죠. 화면 하나에 요청 세 번, 그것도 앞 응답이 와야 뒤 요청 주소를 만들 수 있어서 순차로 이어지곤 했습니다.이렇게 필요한 데이터를 한 번에 못 받아 여러 엔드포인트.. 2026. 7. 5. 인덱스를 걸었는데 더 느려진 이유 인덱스를 걸었는데 왜 더 느려진 이유—읽기를 빠르게 하려다 쓰기를 느리게 만든 경험에서 인덱스의 양면을 정리한 글입니다.인덱스는 어떻게 조회를 빠르게 하는가인덱스를 처음 배울 때 가장 와닿았던 비유는 두꺼운 전공 책 맨 뒤의 색인이었습니다. 500쪽짜리 책에서 "트랜잭션"이라는 단어를 찾는다고 해 보죠. 1쪽부터 한 장씩 넘기며 눈으로 훑으면 언젠가는 찾겠지만, 그 사이 시간은 하염없이 흘러갑니다. 반면 책 뒤 색인에는 단어가 가나다순으로 정렬돼 있고, "트랜잭션 … 210, 233쪽"처럼 위치가 적혀 있습니다. 우리는 색인에서 단어를 빠르게 짚은 뒤 곧장 해당 쪽으로 넘어가죠. 데이터베이스 인덱스가 하는 일이 정확히 이것입니다.인덱스 없이 조회하면 데이터베이스는 테이블의 모든 행을 처음부터 끝까지 읽습.. 2026. 7. 5. 재고가 마이너스가 된 날, 트랜잭션 격리 수준을 배웠습니다 재고가 마이너스가 된 날, 트랜잭션 격리 수준을 배웠습니다—동시 요청이 겹치며 벌어진 사고에서 출발해 격리 수준의 개념과 실전 대처를 정리한 글입니다. 같은 상품을 동시에 주문하면 벌어지는 일작은 커머스 서비스의 백엔드를 맡고 있던 재작년 겨울, 한정 수량 이벤트를 열었던 날의 이야기입니다. 오픈 3분 만에 재고 테이블을 확인했더니 어떤 상품의 qty 컬럼이 -1을 가리키고 있었습니다. 처음엔 눈을 의심했죠. 재고가 음수라니, 물리적으로 존재할 수 없는 값이 데이터베이스에 버젓이 앉아 있었으니까요.당시 재고 차감 코드는 부끄러울 만큼 순진했습니다. 대략 이런 모양이었습니다.// 재고를 조회 후 애플리케이션에서 판정int stock = repo.findQtyById(productId);if (stock >.. 2026. 7. 4. CORS 에러의 진짜 원인 CORS 에러의 진짜 원인을, 하루를 통째로 날린 삽질 끝에 이해한 대로 풀어 쓴 글입니다. 브라우저는 왜 내 요청을 막았는가 CORS 에러를 처음 만나면 대부분 서버가 요청을 거부했다고 오해합니다. 저도 그랬죠. 그런데 사실은 정반대에 가깝습니다. 요청은 서버에 잘 도착했고, 서버는 응답까지 정상적으로 돌려줬는데, 그 응답을 받아 본 브라우저가 "이건 규칙 위반이야"라며 자바스크립트에게 넘겨주지 않는 상황이 CORS 에러입니다. 즉 에러를 내는 주체는 서버가 아니라 브라우저입니다.왜 이런 장치가 있을까요. 브라우저에는 same-origin policy, 즉 "같은 출처끼리만 자유롭게 통신하라"는 기본 원칙이 있습니다. 여기서 출처(origin)는 프로토콜·도메인·포트 세 가지가 모두 같아야 같은 것으로.. 2026. 7. 4. JWT 인증의 구조와, 내가 빠졌던 함정 JWT 인증의 구조와, 내가 빠졌던 함정을 실제 "멀쩡히 쓰다 갑자기 로그아웃되는" 버그를 겪으며 이해한 대로 정리한 글입니다. JWT는 어떻게 로그인을 기억하는가 전통적인 세션 방식은 서버가 "누가 로그인했는지"를 직접 기억합니다. 로그인하면 서버 메모리나 저장소에 세션을 남기고, 브라우저에는 그 세션을 가리키는 열쇠만 쥐여 주죠. 반면 JWT는 접근을 뒤집습니다. 서버가 아무것도 기억하지 않는 대신, "이 사람은 누구이고 무엇을 할 수 있다"는 정보를 토큰 자체에 적어 클라이언트에게 통째로 건네줍니다. 요청이 올 때마다 서버는 그 토큰이 위조되지 않았는지만 검증하면 되죠. 이 토큰은 점 두 개로 나뉜 세 조각으로 되어 있습니다.헤더(header) — 어떤 알고리즘으로 서명했는지 같은 메타 정보가 들어.. 2026. 7. 4. 디바운스와 스로틀, 언제 무엇을 써야 하는가 디바운스와 스로틀, 언제 무엇을 쓸 지 검색창 하나 때문에 서버를 잡아먹을 뻔했던 경험에서 출발해 두 기법의 차이와 실전 선택 기준을 정리합니다. 자동완성 검색창이 서버를 두드려 팬 날 처음 자동완성 검색창을 만들었을 때, 저는 아주 순진하게 짰습니다. 입력창의 onChange에 그대로 API 호출을 붙였죠. 한 글자 칠 때마다 서버로 검색어를 보내고 결과를 받아 목록을 그리는 방식이었습니다. 로컬에서는 완벽해 보였습니다. "제이든"을 치면 관련 결과가 착착 떴으니까요.문제는 배포 다음 날 드러났습니다. 백엔드를 맡은 동료가 "검색 API 호출이 왜 이렇게 많아요?"라고 물어왔죠. 대시보드를 열어 보니 검색 엔드포인트의 초당 요청 수가 평소의 몇 배로 튀어 있었습니다. 원인은 명백했습니다. "제이든"이.. 2026. 7. 3. 이전 1 2 3 4 5 6 7 8 9 다음