[Spring] RestController 와 Controller 차이, RestController 와 ResponseBody 의 관계, RESTful API 란?

dejeong·2024년 10월 22일

DBMS

목록 보기
10/10
post-thumbnail

@Controller@RestController는 Spring Framework에서 웹 요청을 처리하는 두 가지 어노테이션이다. 이 두 어노테이션은 유사한 기능을 제공하지만, 주로 사용되는 목적과 반환되는 응답 형식에서 차이가 있다.

@Controller

일반적인 MVC(Model-View-Controller) 패턴을 사용하는 웹 애플리케이션에서 뷰를 반환하는 데 사용된다.

  • @Controller는 메서드가 반환하는 문자열을 뷰 이름으로 간주하여, 해당 이름에 해당하는 HTML 파일을 렌더링한다.
  • 예를 들어, return "articleList";와 같이 반환하면, articleList.html이라는 뷰를 찾고 이를 클라이언트에 전달한다.
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class WebPageController {

    // 웹 브라우저에서 /greeting URL을 요청하면, greeting.html 파일을 렌더링
    @GetMapping("/greeting")
    public String greeting(Model model) {
        model.addAttribute("message", "Hello, World!");
        return "greeting"; // greeting.html 파일을 반환 (뷰 이름)
    }
}
  • @ControllerHTML 뷰를 반환한다.
  • greeting() 메서드는 greeting.html이라는 템플릿 파일을 찾아 렌더링한다.
  • Model을 사용하여 뷰에 데이터를 전달한다. 여기서는 "message"라는 이름으로 "Hello, World!" 문자열을 전달하고 있다.
  • 결과적으로, 클라이언트는 HTML 페이지를 보게 된다.

@RestController

데이터를 반환하기 위해 사용된다. 보통 JSON 또는 XML 형식으로 클라이언트에게 응답을 보내는 RESTful API를 개발할 때 사용된. 이는 @Controller@ResponseBody를 결합한 형태이다.

  • @RestController는 메서드의 반환 값을 자동으로 JSON 또는 XML로 변환한다. 즉, return한 객체는 HTTP 응답 본문으로 직접 전달된다.
  • @RestController@Controller@ResponseBody를 결합한 것으로, 각 메서드에 대해 반환된 값이 자동으로 바디에 작성된다.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

    // 클라이언트가 /api/greeting URL로 요청하면 JSON 형식의 응답을 반환
    @GetMapping("/api/greeting")
    public String greeting() {
        return "Hello, World!"; // 이 문자열이 JSON 형식으로 클라이언트에게 반환됨
    }
}
  • @RestControllerJSON 또는 XML 데이터를 반환한다.
  • greeting() 메서드는 "Hello, World!"라는 문자열을 반환하지만, 브라우저에는 JSON 응답으로 표시된다.
  • 브라우저나 다른 클라이언트는 이를 데이터로 처리한다. JSON은 API 호출 시 일반적으로 사용하는 응답 형식이다.

차이점

  • 반환 형식:
    • @Controller: 주로 (HTML 파일)를 반환하여 클라이언트에게 웹 페이지를 보여준다.
      예를 들어, 브라우저가 URL /greeting으로 요청하면, 서버는 greeting.html 페이지를 렌더링해 사용자에게 보낸다.
    • @RestController: 주로 데이터(JSON 또는 XML)를 반환하여 클라이언트에게 API 응답을 제공한다.
      클라이언트가 URL /api/greeting으로 요청하면, 서버는 {"message": "Hello, World!"}와 같은 JSON 데이터를 클라이언트에게 응답으로 보낸다.
  • 용도:
    • @Controller: 일반적인 웹 애플리케이션에서 UI를 처리하는 데 사용된다.
    • @RestController: RESTful API를 구현하여 클라이언트와 데이터 통신을 위한 엔드포인트를 제공한다.
  • 선택 기준 :
    • 웹 애플리케이션의 프론트엔드백엔드를 함께 구현하는 경우 @Controller를 사용한다.
    • API 중심의 애플리케이션이나 클라이언트-서버 구조에서 데이터 통신이 주가 되는 경우 @RestController를 사용한다.
// @Controller로 HTML 페이지 반환

@Controller
public class HomeController {

    @GetMapping("/home")
    public String homePage(Model model) {
        model.addAttribute("title", "Welcome to the Home Page");
        return "home"; // home.html을 렌더링
    }
}
// @RestController로 JSON 데이터 반환

@RestController
public class HomeApiController {

    @GetMapping("/api/home")
    public Map<String, String> homeApi() {
        Map<String, String> response = new HashMap<>();
        response.put("title", "Welcome to the API Home Page");
        return response; // JSON 형식으로 응답 {"title": "Welcome to the API Home Page"}
    }
}

@ResponseBody

컨트롤러 메서드에서 데이터를 직접 반환하기 위한 어노테이션이다. 주로 JSON 또는 XML과 같은 형식의 데이터를 반환할 때 사용되며, 이는 보통 RESTful API에서 응답으로 사용된다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.stereotype.Controller;

@Controller
public class ApiController {

    // 클라이언트가 "/api/data" URL로 GET 요청을 보냈을 때
    @GetMapping("/api/data")
    @ResponseBody
    public String getData() {
        // JSON 형식의 데이터를 반환
        return "{\"message\":\"This is some JSON data\"}";
    }
}
  • ResponseBody는 메서드의 반환 값이 직접 HTTP 응답 본문에 포함되도록 한다.
  • 위 코드에서 /api/data 경로로 요청이 들어오면, 서버는 JSON 형식의 데이터를 클라이언트에게 전달한다.
  • 클라이언트는 이 데이터를 API 응답으로 받아 사용할 수 있다.

@RestController와 @ResponseBody의 관계

Spring에서는 @RestController라는 어노테이션도 존재하는데, 이는 사실 @Controller@ResponseBody를 결합한 것이다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiRestController {

    // 클라이언트가 "/api/message" URL로 GET 요청을 보냈을 때
    @GetMapping("/api/message")
    public String getMessage() {
        // JSON 데이터로 응답
        return "{\"message\":\"Hello from the REST API!\"}";
    }
}
  • @RestController데이터만 반환하는 RESTful API를 만들 때 주로 사용되며, 자동으로 모든 메서드가 @ResponseBody를 적용받는다.
  • 즉, @RestController를 사용하면 메서드마다 따로 @ResponseBody를 붙일 필요가 없다.

RESTful API

Representational State Transfer (REST)라는 아키텍처 스타일을 따르는 웹 서비스의 API를 말한다. REST네트워크 상에서 클라이언트와 서버가 서로 통신하는 방식을 정의하는 규칙이다. RESTful API는 이 REST의 원칙을 준수하여 클라이언트가 서버의 리소스에 접근할 수 있도록 설계된 인터페이스이다.

RESTful API는 REST의 원칙을 따라 자원을 HTTP를 통해 제공하는 인터페이스이다. 클라이언트는 HTTP 메서드를 사용해 서버에 요청을 보내고, 서버는 요청에 대한 응답으로 데이터를 반환하거나 리소스를 조작한다. RESTful API는 웹 애플리케이션과 서비스 간의 통신을 효율적으로 처리할 수 있게 도와준다.

RESTful API의 주요 특징

  • 자원(리소스) 기반:
    • RESTful API에서 모든 것은 자원(Resource)이다. 예를 들어, 블로그 시스템에서는 게시글, 댓글, 사용자 등이 자원이 될 수 있다.
    • 자원은 URI(Uniform Resource Identifier)로 식별된다. 자원을 접근하는 경로가 바로 URI이다.
      • 예: /articles, /users/{id}
  • HTTP 메서드:
    RESTful API는 자원에 대한 다양한 동작을 표현하기 위해 HTTP 메서드를 사용한다. 각 메서드는 고유한 의미를 가지고 있다.
    • GET: 자원 조회

    • POST: 자원 생성

    • PUT: 자원 전체 수정 (덮어쓰기)

    • PATCH: 자원 일부 수정

    • DELETE: 자원 삭제

      예를 들어, 블로그에서 게시글을 조회, 생성, 수정, 삭제하는 작업은 각각 다음과 같이 이루어질 수 있다.

    • GET /articles : 게시글 목록 조회

    • POST /articles : 새 게시글 생성

    • PUT /articles/1 : ID가 1인 게시글 수정

    • DELETE /articles/1 : ID가 1인 게시글 삭제

  • 무상태성(Stateless):
    • REST는 무상태성을 보장한다. 즉, 서버는 클라이언트의 이전 요청 상태를 기억하지 않는다. 모든 요청은 독립적이며, 필요한 모든 정보는 요청 자체에 포함되어야 한다.
    • 이 때문에 클라이언트는 서버와의 통신 시마다 필요한 정보를 명시적으로 제공해야 한다. 예를 들어, 인증 정보는 각 요청마다 함께 전달됩니다(보통 HTTP 헤더에 토큰이나 쿠키로)

  • 표현(Representation):
    • 클라이언트와 서버는 자원의 상태를 다양한 형식으로 주고받을 수 있다. 보통 JSON 형식이 많이 사용되며, XML, HTML 등도 사용할 수 있다.
    • 예: 서버에서 /articles로 요청을 보냈을 때, 게시글 목록을 JSON 형식으로 받을 수 있다.

  • 클라이언트-서버 구조:
    • RESTful API는 클라이언트와 서버 간의 명확한 분리를 보장한다. 클라이언트는 사용자 인터페이스(UI)를 관리하고, 서버는 데이터 저장 및 비즈니스 로직을 처리한다.
    • 클라이언트는 서버로부터 필요한 리소스만 요청하고, 서버는 요청에 응답하여 필요한 자원 정보를 제공한다.

  • 캐싱 가능:
    • RESTful API는 HTTP 캐싱을 사용하여 성능을 향상시킬 수 있다. 서버는 응답에 캐싱 가능 여부를 지정하고, 클라이언트는 캐싱된 데이터를 재사용할 수 있다.

RESTful API 예시

블로그 시스템의 RESTful API를 예로 들어 설명하면,

  1. 게시글 목록 조회 (GET)
  • 요청: GET /articles
  • 설명: 게시글 전체 목록을 조회하는 요청
  • 응답: 게시글 목록을 JSON 형식으로 반환
[
    {
        "id": 1,
        "title": "RESTful API란?",
        "content": "RESTful API는..."
    },
    {
        "id": 2,
        "title": "Spring Boot 시작하기",
        "content": "Spring Boot는..."
    }
]
  1. 게시글 작성 (POST)
  • 요청: POST /articles
  • 설명: 새로운 게시글을 작성하는 요청
  • 요청 본문: 새 게시글 정보 (JSON 형식)
{
    "title": "새로운 게시글",
    "content": "이것은 새로운 게시글의 내용입니다."
}
  • 응답: 생성된 게시글 정보
{
    "id": 3,
    "title": "새로운 게시글",
    "content": "이것은 새로운 게시글의 내용입니다."
}
  1. 특정 게시글 조회 (GET)
  • 요청: GET /articles/1
  • 설명: ID가 1인 게시글을 조회하는 요청
  • 응답: 게시글 정보 (JSON 형식)
{
    "id": 1,
    "title": "RESTful API란?",
    "content": "RESTful API는..."
}
  1. 게시글 수정 (PUT)
  • 요청: PUT /articles/1
  • 설명: ID가 1인 게시글의 정보를 수정하는 요청
  • 요청 본문: 수정할 게시글 정보 (JSON 형식)
{
    "title": "RESTful API 설명",
    "content": "RESTful API는 대표적인 웹 서비스 아키텍처 스타일입니다."
}
  • 응답: 수정된 게시글 정보

{
    "id": 1,
    "title": "RESTful API 설명",
    "content": "RESTful API는 대표적인 웹 서비스 아키텍처 스타일입니다."
}
  1. 게시글 삭제 (DELETE)
  • 요청: DELETE /articles/1
  • 설명: ID가 1인 게시글을 삭제하는 요청
  • 응답: 성공 여부를 나타내는 상태 코드 (보통 204 No Content)

RESTful API의 장점

  • 표준화: RESTful API는 HTTP 표준을 따르기 때문에 다양한 언어와 플랫폼에서 쉽게 사용할 수 있다.
  • 유연성: 클라이언트와 서버 간의 의존성이 적고, 서로 독립적으로 개발되고 확장될 수 있다.
  • 확장성: 자원을 명확하게 구분하고 HTTP 메서드를 적절히 사용하여 확장성이 뛰어나다.
  • 무상태성: 서버는 클라이언트의 상태를 기억할 필요가 없으므로 서버의 부담이 줄어든다..

RESTful API의 단점

  • 복잡한 요청 처리: 무상태성을 유지하면서 상태를 관리해야 할 때, 클라이언트가 추가 정보를 지속적으로 보내야 하므로 복잡도가 증가할 수 있다.
  • 표준에 대한 엄격한 요구: RESTful API는 명확한 설계를 요구하기 때문에 규칙을 준수하지 않으면 API가 불완전하거나 혼란스러워질 수 있다.
profile
룰루

0개의 댓글