서버가 요청을 받는다는 의미

북금곰·2026년 7월 14일

백엔드 기본 지식

목록 보기
3/29

서버가 요청을 받는다는 것은 클라이언트가 보낸 HTTP 메시지를 읽고, 그 안의 메서드, 주소, 헤더, 바디를 바탕으로 어떤 일을 할지 결정하는 것이다.

다른 사람들은 어떻게 말할까?

MDN의 HTTP 메시지 문서에서는 HTTP가 클라이언트와 서버 사이에서 데이터를 주고받기 위해 사용하는 메시지 구조를 설명한다.

HTTP 메시지는 크게 두 종류가 있다.

요청 Request: 클라이언트가 서버에게 보내는 메시지
응답 Response: 서버가 요청에 대해 돌려주는 메시지

요청 메시지에는 보통 다음 정보가 들어 있다.

Start line: 어떤 메서드로, 어떤 경로에 요청하는지
Headers: 요청에 대한 부가 정보
Body: 서버에 보내는 실제 데이터

Spring 공식 문서의 DispatcherServlet 설명에서는 Spring MVC가 HTTP 요청을 받으면 DispatcherServlet이 요청을 적절한 handler, 즉 Controller 쪽으로 연결한다고 설명한다.

즉, Spring Boot에서 우리가 Controller 메서드를 작성할 수 있는 이유는 그 앞단에서 HTTP 요청을 읽고, 알맞은 메서드를 찾아주는 흐름이 있기 때문이다.

쉽게 설명하자면

처음에는 이런 표현이 조금 추상적으로 느껴진다.

“서버가 요청을 받는다.”

이 말을 너무 단순하게 생각하면 서버가 그냥 URL만 보는 것처럼 느껴질 수 있다.

하지만 서버는 URL만 보는 것이 아니다.

예를 들어 이런 요청이 있다고 해보자.

POST /users HTTP/1.1
Host: example.com
Content-Type: application/json

{
  "name": "junior",
  "email": "junior@example.com"
}

서버는 이 요청에서 여러 정보를 읽는다.

POST: 데이터를 보내서 어떤 처리를 해달라는 의미
/users: 사용자가 요청한 대상 경로
Content-Type: 요청 바디가 JSON 형식이라는 정보
Body: 실제로 서버에 전달하고 싶은 데이터

그러니까 “요청을 받는다”는 말은 단순히 주소 하나를 받는 것이 아니라, 클라이언트가 보낸 메시지 전체를 해석하는 일에 가깝다.

회사로 비유하자면

서버를 회사 접수처라고 생각해보자.

누군가 접수처에 서류를 들고 와서 말한다.

"신규 회원 등록하러 왔습니다."

접수처 직원은 단순히 사람만 보는 것이 아니라 여러 가지를 확인한다.

무슨 업무인가?
어느 부서로 보내야 하나?
서류 형식은 맞나?
필수 정보가 빠지지 않았나?
처리 결과를 어떻게 알려줘야 하나?

HTTP 요청도 비슷하다.

메서드: 무슨 일을 원하는가?
경로: 어떤 자원에 대한 요청인가?
헤더: 요청을 이해하는 데 필요한 부가 정보는 무엇인가?
바디: 실제로 전달된 데이터는 무엇인가?

백엔드 개발자는 이 정보를 읽고, 적절한 코드로 연결되도록 API를 만든다.

코드 예제

브라우저나 프론트엔드 코드에서 다음 요청을 보낸다고 해보자.

await fetch("/users", {
  method: "POST",
  headers: {
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    name: "junior",
    email: "junior@example.com"
  })
});

Spring Boot 서버에서는 이 요청을 이렇게 받을 수 있다.

@RestController
public class UserController {

    @PostMapping("/users")
    public UserResponse createUser(@RequestBody UserCreateRequest request) {
        return new UserResponse(1L, request.name(), request.email());
    }
}

여기서 각 부분은 요청 메시지와 연결된다.

@PostMapping("/users")
-> POST /users 요청을 이 메서드가 처리한다.

@RequestBody
-> HTTP 요청 바디의 JSON 데이터를 Java 객체로 바꿔 받는다.

UserCreateRequest
-> 클라이언트가 보낸 데이터를 담는 요청 DTO다.

UserResponse
-> 서버가 클라이언트에게 돌려줄 응답 DTO다.

요청 DTO는 이렇게 만들 수 있다.

public record UserCreateRequest(
    String name,
    String email
) {
}

응답 DTO는 이렇게 둘 수 있다.

public record UserResponse(
    Long id,
    String name,
    String email
) {
}

이 작은 예제에서 서버가 하는 일은 다음과 같다.

1. POST /users 요청을 받는다.
2. 요청 바디의 JSON을 읽는다.
3. JSON을 UserCreateRequest 객체로 바꾼다.
4. Controller 메서드를 실행한다.
5. UserResponse를 JSON 응답으로 돌려준다.

프로젝트에서 조심할 부분

서버가 요청을 받았다고 해서 그 요청을 그대로 믿으면 안 된다.

클라이언트는 언제든 잘못된 값을 보낼 수 있다.

{
  "name": "",
  "email": "not-email"
}

또는 필요한 값을 아예 보내지 않을 수도 있다.

{
  "name": "junior"
}

그래서 서버는 요청을 받은 뒤 반드시 확인해야 한다.

필수 값이 있는가?
형식이 맞는가?
현재 사용자가 이 요청을 할 권한이 있는가?
요청한 데이터가 실제로 존재하는가?
요청을 처리하면 시스템 규칙에 어긋나지 않는가?

프론트엔드에서도 검증을 할 수 있지만, 최종 검증은 백엔드에서 해야 한다. 서버는 시스템의 데이터를 지키는 마지막 문이기 때문이다.

또 하나 중요한 점은 Controller가 너무 많은 일을 하지 않게 하는 것이다.

Controller는 요청을 받는 입구 역할에 가깝다. 실제 비즈니스 판단은 보통 Service에서 처리한다.

Controller: 요청을 받고 필요한 값을 꺼낸다
Service: 비즈니스 규칙을 처리한다
Repository: 데이터베이스와 대화한다

이 역할을 나누면 요청이 들어온 뒤 서버 내부에서 어떤 일이 일어나는지 훨씬 읽기 쉬워진다.

정리해보자

“서버가 요청을 받는다”는 말은 생각보다 많은 의미를 담고 있다.

서버는 HTTP 요청에서 다음 정보를 읽는다.

메서드
경로
헤더
바디

그리고 그 정보를 바탕으로 적절한 코드를 실행한다.

Spring MVC에서는 이 흐름에서 DispatcherServlet이 요청을 받아 알맞은 handler로 연결하고, 우리는 보통 Controller 메서드에서 그 요청을 처리한다.

나는 이 개념을 이렇게 정리하고 싶다.

서버는 요청을 그냥 받는 것이 아니라, 요청 메시지를 해석하고 처리할 코드로 연결한다.

이 관점이 생기면 @GetMapping, @PostMapping, @RequestBody, @PathVariable, @RequestParam 같은 어노테이션도 단순 문법이 아니라 HTTP 요청을 Java 코드로 연결하는 도구로 보이기 시작한다.

profile
주니어개발자

0개의 댓글