[데브코스] Spring Boot REST API 실습 (4·5강)

zuno·2025년 12월 19일

Jackson, 순환참조, 게시글 목록/단건 조회 API 구현

이번 글에서는 Spring Boot REST API 실습 4강과 5강 내용을 한 번에 정리한다.
게시글 목록 조회와 단건 조회 API를 구현하면서
Jackson의 역할, 엔티티 순환참조 문제, @RestController, @RequestMapping 개념을 함께 정리했다.


1️⃣ REST API 방식이란?

REST API 방식에서는 백엔드가 화면을 렌더링하지 않는다.

  • 백엔드: 데이터(JSON) 제공
  • 프론트엔드(React, Next.js 등): 화면 렌더링 및 사용자 인터랙션 처리

따라서
👉 컨트롤러가 JSON만 응답하는 것은 전혀 이상한 구조가 아니다.
👉 화면 구성은 프론트 애플리케이션의 책임이다.


2️⃣ Jackson이란?

▪ Jackson 정의

Jackson은 Java 객체와 JSON 간 변환을 담당하는 라이브러리이다.

  • Java 객체 → JSON 변환
  • JSON → Java 객체 변환

Spring Boot에서 REST API를 구현할 때
클라이언트와 서버 간 데이터 교환을 자동으로 처리한다.


▪ Jackson의 주요 기능

직렬화 (Serialization)

Java 객체 → JSON 문자열

역직렬화 (Deserialization)

JSON 문자열 → Java 객체

Spring Boot에서는
spring-boot-starter-web에 기본 포함되어 있어
별도의 설정 없이 바로 사용할 수 있다.


3️⃣ 순환참조 문제 (4강 핵심)

▪ 문제 상황

엔티티 간 양방향 연관관계가 존재할 경우
Jackson 직렬화 과정에서 무한 루프(순환참조)가 발생할 수 있다.

▪ 예시 구조

// Post 엔티티
@OneToMany(mappedBy = "post")
private List<PostComment> comments;
// PostComment 엔티티
@ManyToOne
private Post post;

▪ 직렬화 흐름

Post
 → comments
   → PostComment
     → post
       → comments
         → ...

👉 무한 반복 → StackOverflowError 발생


4️⃣ 순환참조 해결 방법

✅ 1. @JsonIgnore 사용

@Entity
@Getter
@NoArgsConstructor
public class PostComment extends BaseEntity {

    @ManyToOne
    @JsonIgnore
    private Post post;

    private String content;
}
  • 특정 필드를 JSON 직렬화 대상에서 제외
  • 가장 간단하고 빠른 해결 방법

✅ 2. @JsonManagedReference / @JsonBackReference

  • 부모 → 자식 방향만 JSON 포함
  • 자식 → 부모 방향은 직렬화 제외

✅ 3. DTO 사용 ⭐ (가장 권장)

  • 엔티티를 직접 반환하지 않음
  • 응답 전용 DTO 생성
  • 실무에서 가장 일반적인 방식

5️⃣ REST API 컨트롤러 구현 (4강)

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/posts")
public class ApiV1PostController {

    private final PostService postService;

    @GetMapping
    public List<Post> getItems() {
        return postService.findAll();
    }
}

▪ @RestController 의미

@RestController = @Controller + @ResponseBody
  • 모든 메서드의 반환값을 JSON으로 응답
  • REST API 전용 컨트롤러 선언

6️⃣ 클래스 레벨 @RequestMapping

@RequestMapping("/api/v1/posts")
  • 컨트롤러 전체의 공통 URL 접두어
  • 메서드 레벨 매핑과 결합되어 최종 URL 생성
@GetMapping
→ GET /api/v1/posts

7️⃣ 글 단건 조회 API 구현 (5강)

@GetMapping("/{id}")
public Post getItem(@PathVariable int id) {
    return postService.findById(id).get();
}

▪ 설명

  • GET /api/v1/posts/{id} 요청 처리
  • URL 경로의 {id} 값을 @PathVariable로 바인딩
  • 게시글 단건 조회 후 JSON으로 응답

👉 이후 화면 렌더링은 프론트엔드에서 수행한다.


8️⃣ 컨트롤러 메서드 이름과 접근 제어자

▪ 메서드 이름은 중요할까?

아니다.
Spring은 메서드 이름을 보지 않는다.

Spring이 기준으로 삼는 것:

  • 매핑 어노테이션 (@GetMapping)
  • URL 경로
  • HTTP Method

메서드 이름은 가독성을 위한 요소이다.


▪ 왜 public 메서드여야 할까?

컨트롤러 메서드는 반드시 public이어야 한다.

  • Spring이 리플렉션을 통해 외부에서 호출
  • private / protected 사용 시 오류 발생

9️⃣ REST API 방식 vs 타임리프 방식 비교 (6강 연결)

구분REST API 방식타임리프 방식
역할 분담백엔드: 데이터 제공
프론트: 화면 렌더링
백엔드: 데이터 + 화면
응답 형태JSONHTML
유지보수프론트 중심 수정백엔드 + 화면 수정
재사용성모바일/웹 등 확장 가능웹 전용
테스트API 테스트화면 렌더링 포함
확장성높음제한적

🔚 정리

  • REST API 서버는 JSON만 반환한다
  • Jackson은 Java ↔ JSON 변환 담당
  • 엔티티 직접 반환 시 순환참조 문제 발생 가능
  • @JsonIgnore 등으로 해결 가능
  • @RestController + @RequestMapping 구조가 기본
  • 단건 조회 API는 REST 설계의 핵심 단계

💡 한 줄 요약

REST API 방식에서는 서버는 데이터만 책임지고,
화면과 사용자 경험은 프론트엔드 애플리케이션이 담당한다.

0개의 댓글