[스프링 로드맵] A-1. REST 입문 - JSON이 응답되는 이유

2026. 1. 19. 17:03·백엔드
  • 참고자료: https://spring.io/guides/gs/rest-service

Spring Getting Started의 “Building a RESTful Web Service” 예제는 GET /greeting 요청을 받으면 서버가 Greeting 객체를 만들어 JSON으로 응답하는 가장 작은 REST API 샘플이다.

이 글의 목표는 예제 코드 자체를 외우는 게 아니라, “요청이 들어와서 JSON이 나가기까지”의 흐름을 한 번에 정리하는 것이다.


1. 이 예제가 하는 일

  • 클라이언트가 GET /greeting을 호출하면
  • 서버는 { "id": 1, "content": "Hello, World!" } 같은 JSON을 반환한다.
  • GET /greeting?name=User처럼 쿼리 파라미터를 주면 World 대신 User로 응답이 바뀐다.

2. JSON이 나오는 이유

스프링 MVC에서 컨트롤러 메서드가 값을 반환하면, 기본적으로 두 가지 경로 중 하나로 처리된다.

2-1) 뷰 렌더링(HTML) 방식: @Controller

  • 컨트롤러에서 문자열을 반환하면 대체로 “뷰 이름”으로 해석한다.
  • 예: return "hello"; → hello.html 또는 hello.jsp를 찾아 렌더링

2-2) 데이터(JSON) 응답 방식: @ResponseBody / @RestController

  • 반환값을 “뷰 이름”으로 보지 않고 HTTP 응답 바디에 그대로 쓰도록 한다.
  • 반환 타입이 객체라면 JSON 같은 형태로 변환되어 바디에 기록된다.

즉, REST API에서 “JSON이 나오는 이유”는 한 문장으로 정리된다.

@RestController(또는 @ResponseBody)가 붙어 있으면 반환값이 뷰가 아니라 응답 바디로 간다.


3. 예제 코드에서 @가 붙은 것들 역할

예제 컨트롤러는 대략 이런 형태다.

@RestController
public class GreetingController {

  private static final String template = "Hello, %s!";
  private final AtomicLong counter = new AtomicLong();

  @GetMapping("/greeting")
  public Greeting greeting(@RequestParam(defaultValue = "World") String name) {
    return new Greeting(counter.incrementAndGet(), template.formatted(name));
  }
}

3-1) @RestController

  • “이 클래스는 HTTP 요청을 처리하는 컨트롤러다” + “반환값은 뷰가 아니라 응답 바디로 쓴다”를 합친 선언
  • 내부적으로는 @Controller + @ResponseBody와 같은 의미로 이해하면 된다.

3-2) @GetMapping("/greeting")

  • GET /greeting 요청을 이 메서드로 연결한다.
  • @RequestMapping(method = GET, path="/greeting")의 축약형이다.

3-3) @RequestParam(defaultValue="World")

  • 쿼리 파라미터를 메서드 인자로 바인딩한다.
  • GET /greeting?name=User → name = "User"
  • name이 없으면 defaultValue가 적용되어 name = "World"

중요한 규칙: @RequestParam 같은 HTTP 입력 바인딩 애너테이션은 보통 컨트롤러에서만 사용한다.

서비스 계층은 HTTP를 모르는 형태(순수 자바 메서드)로 두는 게 테스트/유지보수에 유리하다.


4. 객체가 JSON으로 바뀌는 과정: HttpMessageConverter

컨트롤러 메서드는 Greeting 객체를 return할 뿐인데, 응답은 JSON이다.

이 변환을 담당하는 게 HttpMessageConverter다.

  • 응답 방향: 자바 객체 → JSON → 응답 바디
  • 요청 방향(나중에 @RequestBody에서 등장): 요청 바디(JSON) → 자바 객체

컨트롤러가 JSON으로 직접 바꾸는 게 아니다.

스프링 MVC가 컨트롤러 호출 전/후에 끼어들어 HttpMessageConverter로 변환한다.

프로젝트에 Jackson이 포함되어 있으면, 스프링은 JSON 변환용 컨버터를 자동으로 선택한다. 그래서 별도 설정 없이도 객체가 JSON으로 직렬화된다.


5) 요청 → 응답 전체 흐름(한 번에 보기)

클라이언트
  |
  | GET /greeting?name=User
  v
DispatcherServlet (Spring MVC의 진입점)
  |
  | 어떤 컨트롤러 메서드인지 찾음(@GetMapping)
  v
GreetingController.greeting(...)
  |
  | @RequestParam으로 name 바인딩
  | Greeting 객체 생성 후 return
  v
HttpMessageConverter(Jackson)
  |
  | Greeting -> JSON 변환
  v
HTTP Response (200 OK)
{ "id": 2, "content": "Hello, User!" }

여기서 DispatcherServlet은 “모든 요청을 먼저 받는 관문” 정도로만 이해해도 충분하다. (스프링 MVC에서 프론트 컨트롤러 역할)


6. 왜 AtomicLong? (싱글톤과 동시성)

예제에선 id를 1씩 증가시키려고 counter를 필드로 둔다.

그런데 스프링에서 컨트롤러는 보통 싱글톤 빈으로 생성된다.

  • 여러 사용자가 동시에 호출해도 같은 컨트롤러 인스턴스를 공유한다.
  • 그 상태에서 counter++ 같은 증가 연산을 하면, 동시 요청에서 값이 꼬일 수 있다.

AtomicLong.incrementAndGet()은 증가 연산을 원자적으로 처리해서 동시성 환경에서도 값이 안전하게 증가한다.

참고로 컨트롤러에 상태를 두기보다 DB의 자동 증가 키나 UUID 같은 전략을 쓰는 편이 일반적이다. 이 예제는 “동시성 안전한 증가”를 보여주려는 단순 예시다.

 

정리

@RestController가 반환값을 응답 바디로 보내도록 만들고, 실제 JSON 변환은 스프링의 HttpMessageConverter(Jackson)가 수행한다. @RequestParam은 쿼리 파라미터를 컨트롤러 인자로 바인딩하는 장치다.

 

'백엔드' 카테고리의 다른 글

[스프링 로드맵] B-3. DI/Bean 실전 - @Autowired, @Qualifier, Profile  (0) 2026.01.19
[스프링 로드맵] B-2. DI/Bean 내부 - 빈 등록 방식과 라이프사이클  (1) 2026.01.19
[스프링 로드맵] B-1. DI/Bean 기본 - new 지옥에서 벗어나기  (1) 2026.01.19
[스프링 로드맵] A-2. REST 확장 - POST/PUT/DELETE와 ResponseEntity  (0) 2026.01.19
[스프링 로드맵] 0편. 전체 그림 – REST부터 JPA까지 한 번에 보기  (0) 2026.01.19
'백엔드' 카테고리의 다른 글
  • [스프링 로드맵] B-2. DI/Bean 내부 - 빈 등록 방식과 라이프사이클
  • [스프링 로드맵] B-1. DI/Bean 기본 - new 지옥에서 벗어나기
  • [스프링 로드맵] A-2. REST 확장 - POST/PUT/DELETE와 ResponseEntity
  • [스프링 로드맵] 0편. 전체 그림 – REST부터 JPA까지 한 번에 보기
samsam031
samsam031
samsam031 님의 블로그 입니다.
  • samsam031
    samsam031 님의 블로그
    samsam031
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 디지털포렌식
      • 드림핵 문제풀이
      • 대외활동
      • 개발 실습
      • 컴퓨터 보안
      • 클라우드
      • 자격증
      • 자연어처리
      • 백엔드
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
samsam031
[스프링 로드맵] A-1. REST 입문 - JSON이 응답되는 이유
상단으로

티스토리툴바