RicoCheesethe studio log · v2.0
Live · KRRead posts
목록으로
개발PUBLISHED · 2026년 7월 14일·10 MIN READ

[스프링 요청 파이프라인] 요청 하나가 서버를 통과하는 전체 흐름 (1)

웹사이트 버튼 하나 눌렀을 뿐인데 요청은 서버 안에서 몇 개의 관문을 통과한다. 그 관문들이 왜 하나가 아니라 여럿인지, 회사 건물 방문에 빗대어 5부작으로 풀어본다.

#spring#java#backend#web#request-lifecycle
Sleek corporate building lobby with marble walls and glass windows

버튼을 눌렀을 뿐인데 #

로그인 버튼을 누른다. 0.2초쯤 뒤에 "환영합니다"라는 문구가 뜬다. 사용자 입장에서는 이게 전부다. 버튼 누르고, 화면 바뀌고, 끝.

그런데 그 0.2초 사이 서버 안에서는 아무 일도 안 일어난 게 아니다. 요청이라는 게 하나 만들어진다. 그 요청은 몇 개의 문을 순서대로 통과하고 담당자를 만나 볼일을 본 다음, 다시 문을 거쳐 되돌아 나온다. 이 시리즈는 그 0.2초 안에서 벌어지는 일을 5부에 걸쳐 뜯어본다. 1화인 이번 글은 전체 지도를 먼저 그려두는 편이다.

손님이 회사 건물에 들어왔다 #

비유는 이거다. 당신이 웹사이트나 앱에 요청 하나를 보내는 건, 손님 한 명이 어떤 회사 건물에 방문하는 것과 같다.

  • 요청(request) = 건물에 들어온 손님
  • 서버 = 그 손님을 맞이하는 회사 건물
  • 응답(response) = 손님이 볼일을 마치고 원하는 서류를 받아 건물을 나서는 것

손님이 건물에 들어온다고 곧장 자기가 만나고 싶은 직원 책상으로 달려가지는 않는다. 정문을 지나 로비를 거치고, 부서 앞에서 한 번 더 확인을 받은 다음에야 그 직원 앞에 앉는다. 스프링으로 짠 서버도 똑같다. 요청이 들어오면 곧바로 개발자가 짠 코드(컨트롤러)로 가지 않는다. 몇 개의 관문을 순서대로 지난다.

왜 곧장 담당자한테 가면 안 되는가 #

여기서 자연스러운 질문이 하나 나온다. 어차피 결국 담당 직원이 처리할 일이면, 손님을 왜 곧장 그 자리로 안내하지 않을까? 관문이 많을수록 느려지고 복잡해질 텐데.

답은 "한 사람이 다 하면 그 한 사람이 너무 많은 일을 떠안는다"는 것이다. 만약 담당 직원 한 명이 정문 보안검색에 손님 안내, 신분증 확인, 게다가 본업인 서류 처리까지 다 떠맡아야 한다면 어떨까. 일이 조금만 바뀌어도 그 직원의 업무 전체가 흔들린다. 보안 규정이 바뀌면 모든 직원이 각자 코드를 고쳐야 하고, 안내 방식이 바뀌어도 마찬가지다.

그래서 회사는 역할을 나눈다. 경비는 경비만, 안내는 안내만, 접수는 접수만 본다. 각자 자기 역할에만 집중하면 유지보수도 쉬워지고 같은 경비 인력을 다른 부서에 그대로 재사용하기도 쉬워진다. 보안 문제가 생겼을 때 어디를 고쳐야 할지 명확해지는 것도 덤이다. 개발자들은 이걸 관심사 분리(separation of concerns)라고 부른다. 스프링이 요청 하나를 처리하는 데 여러 관문을 두는 이유도 결국 이거다.

이번 손님의 동선 #

정리하면 이번 시리즈에서 손님(요청)이 지나가는 동선은 이렇다.

untitled
text
GET /mypage HTTP/1.1
Host: mycompany.com

위 세 줄이 손님이 들고 온 신분증이자 방문 목적이라고 생각하면 된다. "mycompany.com이라는 건물의 mypage라는 부서를 만나러 왔다"는 뜻이다. 이 손님은 다음 순서로 건물을 통과한다.

  1. 경비실 — 정문 보안검색. 건물 안에 들어오기 전에 수상한 손님을 먼저 거른다. (2화에서 Filter로 다룬다)
  2. 로비 안내데스크 — "몇 층 몇 부서로 가시면 됩니다"를 알려주는 곳. 모든 손님이 반드시 거치는 단일 창구다. (3화에서 DispatcherServlet으로 다룬다)
  3. 부서 접수창구 — 담당 직원을 만나기 직전, 한 번 더 신분과 용건을 확인하는 곳. (4화에서 Interceptor로 다룬다)
  4. 담당 직원 — 실제로 서류를 처리하고, 필요하면 뒤쪽 팀(자료 보관실 등)에 요청해서 결과물을 만들어 손님에게 건넨다. (5화에서 Controller와 그 뒤편을 다룬다)

이 네 관문의 이름과 역할을 이번 화에서 다 외울 필요는 없다. 지금은 "관문이 네 개고, 순서가 있다" 정도만 기억하면 충분하다.

경비실은 사실 다른 회사 소속이다 #

한 가지만 미리 흘려두려 한다. 이 네 관문이 전부 같은 소속은 아니라는 점이다.

경비실은 사실 이 회사 정직원이 아니다. 건물 전체를 관리하는 시설관리 업체 소속이다. 그 건물에 어떤 회사가 몇 개나 입주해 있든, 경비실은 건물 전체의 정문에서 똑같이 일한다. 반면 3번 부서 접수창구는 이 회사가 직접 고용한 우리 직원이다. 회사 내부 시스템에 접근할 수 있고, 사내 메신저로 다른 직원과 바로 연락도 된다.

기술 용어로 옮기면, 경비실에 해당하는 Filter는 스프링이 관리하는 영역 바깥, 즉 톰캣 같은 WAS(웹 애플리케이션 서버) 스펙에 속한다. 반면 접수창구에 해당하는 Interceptor는 스프링이 직접 관리하는 영역 안에 있어서, 스프링이 만들어둔 다른 부품(빈)을 자유롭게 가져다 쓸 수 있다. "스프링 밖"과 "스프링 안"의 경계가 이 두 관문 사이에 그어져 있다는 뜻이다. 왜 이 구분이 중요한지는 2화와 4화에서 각각 다시 짚는다.

그래서 이게 왜 중요한데 #

실무에서 이 지도가 쓸모 있는 순간은 보통 둘 중 하나다.

하나는 "이 로직을 어디에 넣어야 하나"를 고민할 때다. CORS 처리나 인코딩처럼 스프링 자체를 몰라도 되는 일은 경비실(Filter) 급에서 끝내는 게 맞고, 로그인 여부처럼 스프링 내부 정보가 필요한 일은 접수창구(Interceptor) 급에서 하는 게 맞다. 이 구분을 모르면 모든 로직을 컨트롤러 안에 욱여넣게 되고, 나중에 그 컨트롤러는 손댈 때마다 무섭다.

다른 하나는 요청이 어디선가 막혔을 때다. 응답이 이상하게 나오거나 아예 안 나올 때, "경비실에서 막혔나, 안내데스크까지는 왔나, 접수창구에서 걸렸나"를 순서대로 짚어갈 수 있으면 디버깅이 반이 된다. 순서를 모르면 로그를 어디서부터 봐야 할지조차 감이 안 잡힌다.

다음 화 예고 #

2화에서는 첫 번째 관문인 경비실, 즉 Filter를 자세히 들여다본다. 건물 관리회사 소속이라 스프링 코드를 몰라도 일할 수 있다는 게 무슨 뜻인지, 그리고 이 경비실 개념 위에 보안 시스템(Spring Security)이 어떻게 세워지는지를 다룰 예정이다.