REST 서비스 구현

김우진·2026년 2월 20일

Spring

목록 보기
11/17
post-thumbnail

[Spring] 10. REST 서비스 구현

앱 간의 데이터 교환을 위한 REST 엔드포인트를 구축하고, 효율적인 응답 및 예외 관리 방법을 정리했습니다.


1. REST 서비스를 이용한 앱 간 데이터 교환

REST 엔드포인트란?

  • 두 앱 간 통신을 구현하는 방법으로, 한 앱이 HTTP를 통해 접근 가능하도록 기능을 노출한 지점입니다.
  • 웹 프로토콜을 따르기 때문에 '웹 서비스'라고도 부릅니다.
  • 스프링에서는 HTTP 메서드와 경로에 매핑된 컨트롤러 액션이 곧 엔드포인트가 됩니다.

REST 구현 시 MVC 흐름의 변화

  • 클라이언트는 뷰(HTML)가 아닌 데이터 자체를 필요로 합니다.
  • 따라서 뷰 리졸버(View Resolver)가 필요 없으며, 디스패처 서블릿은 뷰를 렌더링하지 않고 HTTP 응답 본문을 직접 반환합니다.

2. REST 엔드포인트 구현 애너테이션

  • @ResponseBody: 메서드가 HTTP 응답을 직접 반환한다는 것을 디스패처 서블릿에 알립니다.
  • @RestController: @Controller@ResponseBody를 합친 애너테이션입니다. 클래스 내 모든 메서드에 @ResponseBody가 적용되는 효과가 있습니다.

3. HTTP 응답 관리와 DTO

구성 요소

  1. 응답 본문(Body): 클라이언트에 전달할 실제 데이터입니다.
  2. 응답 헤더(Header): 데이터에 대한 메타 정보입니다.
  3. 응답 상태(Status): 요청 처리 결과(성공, 실패 등)를 나타냅니다.

데이터 전송 객체 (DTO)

  • 두 앱 간에 전송되는 데이터를 모델링하기 위해 사용하는 객체입니다.
  • 객체나 컬렉션 인스턴스는 주로 JSON 포맷으로 변환되어 전송됩니다.
 @GetMapping("/all")
    public List<Country> countries(){
        Country c1 = Country.of("France",67);
        Country c2 = Country.of("Spain",47);

        return List.of(c1,c2);
    }

4. HTTP 응답 상태 및 예외 관리

주요 HTTP 상태 코드

  • 200 OK: 요청 성공.
  • 400 Bad Request: 클라이언트 요청 방식이 서버 예상과 다를 때.
  • 404 Not Found: 요청한 리소스가 존재하지 않을 때.
  • 500 Internal Server Error: 서버 측 내부 예외 발생 (백엔드 결함).

예외 처리 전략

  1. 컨트롤러 액션 수준: 액션 메서드 내에서 직접 처리. (코드 중복 위험이 큼)
  2. REST 컨트롤러 어드바이스 (@RestControllerAdvice): * 예외 처리 로직을 별도 클래스로 분리하여 전역적으로 관리합니다.
    • @ExceptionHandler: 특정 예외가 발생했을 때 이를 가로챌 메서드를 지정(예외 핸들러)합니다.
package com.example.spring_10.controllers;

import com.example.spring_10.exception.NotEnoughMoneyException;
import com.example.spring_10.model.ErrorDetails;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class ExceptionControllerAdvice {

    @ExceptionHandler(NotEnoughMoneyException.class)
    public ResponseEntity<ErrorDetails> exceptionNotEnoughMoneyHandler(){
        ErrorDetails errorDetails = new ErrorDetails();
        errorDetails.setMessage("Not enough money to make the payment");
        return ResponseEntity
                .badRequest()
                .body(errorDetails);
    }
}

5. 요청 본문(RequestBody) 사용

  • 용도: 많은 양의 데이터를 서버로 전송할 때 사용합니다.
  • 방법: 컨트롤러 액션 매개변수에 @RequestBody를 추가합니다.
  • 특징: 주로 JSON 형식을 사용하며, 스프링이 JSON 문자열을 객체 타입으로 디코딩하지 못하면 400 Bad Request를 반환합니다.
package com.example.spring_10.controllers;

import com.example.spring_10.exception.NotEnoughMoneyException;
import com.example.spring_10.model.ErrorDetails;
import com.example.spring_10.model.PaymentDetails;
import com.example.spring_10.services.PaymentService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.logging.Logger;

@RestController
public class PaymentController {
    private final PaymentService paymentService;

    public PaymentController(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    private static Logger logger = Logger.getLogger(PaymentController.class.getName());

    @PostMapping("/payment")
    public ResponseEntity<PaymentDetails> makePayment(
            @RequestBody PaymentDetails paymentDetails
    ){

        logger.info("Receivced payment " + paymentDetails.getAmount());

        return ResponseEntity
                .status(HttpStatus.ACCEPTED)
                .body(paymentDetails);
    }
}

💡 요약

  1. REST 컨트롤러는 HTML 대신 JSON 데이터를 직접 반환한다.
  2. ResponseEntity를 사용하면 응답 상태와 헤더를 정교하게 제어할 수 있다.
  3. @RestControllerAdvice를 통해 비즈니스 로직(Service)과 예외 처리 로직을 깔끔하게 분리하자.
  4. 대량의 데이터 전송 시에는 @RequestBodyJSON을 활용한다.

#Spring #REST_API #RestController #DTO #GlobalExceptionHandler #백엔드공부

0개의 댓글