자바 웹 REST

Dear·2025년 6월 27일

TIL

목록 보기
50/74

💙 AJAX

Asynchronous JavaScript And XML
웹 페이지를 새로 고침하지 않고도 서버와 비동기적으로 데이터를 주고받는 기술이다.

페이지 전체를 새로고침하지 않고도 필요한 데이터만 주고받아서 빠른 사용자 경험(UX)을 제공한다.

Spring에서 AJAX 사용하는 흐름

  1. 클라이언트(브라우저) : JavaScript로 AJAX 요청을 보낸다. (fetch, jQuery.ajax() 등)
  2. 서버(Spring Controller) : JSON 등 형식으로 응답을 처리
  3. 클라이언트 : 받은 응답으로 웹 페이지 일부를 업데이트

JavaScript (AJAX 요청)

// JavaScript fetch 사용 예시
fetch('/hello', {
    method: 'GET'
})
.then(response => response.json())
.then(data => {
    console.log(data.message); // "안녕하세요"
});

Spring Controller

@RestController
public class HelloController {

    @GetMapping("/hello")
    public Map<String, String> sayHello() {
        Map<String, String> response = new HashMap<>();
        response.put("message", "안녕하세요");
        return response;  // JSON 응답
    }
}

💙 REST

REpresentational State Transfer
웹에서 자원을 정의하고 자원에 대한 행위를 HTTP 메소드로 표현하는 아키텍쳐 스타일

자원을 URI로 표현하고, 해당 자원에 대한 동작은 HTTP 메서드(GET, POST, PUT, DELETE 등)로 정의

HTTP 메서드와 의미 매핑

HTTP 메서드설명예시
GET자원 조회/users/1 → id가 1인 사용자 정보 가져오기
POST자원 생성/users + body → 새 사용자 등록
PUT자원 전체 수정/users/1 + body → id가 1인 사용자 정보 전체 수정
PATCH자원 일부 수정/users/1 + body → 사용자 일부 정보만 수정
DELETE자원 삭제/users/1 → id가 1인 사용자 삭제

💙 RESTful

REST 원칙을 잘 지켜서 설계한 웹 서비스나 API

장점

  • URL이 직관적이라 이해하기 쉽다
  • HTTP 표준만 사용하므로 별도 기술 없이도 사용 가능
  • 서버와 클라이언트가 완전히 분리되어 개발이 쉽다
  • 확장성과 유연성이 높다

예시

동작URL메서드
회원 전체 조회/membersGET
회원 등록/membersPOST
회원 상세 조회/members/1GET
회원 정보 수정/members/1PUT
회원 삭제/members/1DELETE

💙 @Controller와 @RestController 차이


항목@Controller@RestController (Spring 4.0+)
설명기존 Spring MVC 방식API 응답 전용 컨트롤러
반환 대상View (JSP 등)데이터 (JSON, XML 등)
사용 목적사용자에게 웹 페이지 제공프론트엔드 또는 외부 시스템과 데이터 통신
반환 타입ModelAndView 또는 String(뷰 이름)객체 → 자동으로 JSON/XML 변환
구성 요소단독 사용@Controller + @ResponseBody 조합
자동 변환없음 (ViewResolver를 통해 View 렌더링)있음 (@ResponseBody로 자동 JSON/XML 변환)
사용 예게시판, 로그인 화면 등 HTML UI 제공REST API 서버 구축, Ajax 응답 등

@ResponseBody

메소드에서 반환한 데이터를 HTTP 응답 바디에 그대로 담아 전송하도록 만드는 어노테이션

메서드 반환값을 View로 처리하지 말고, HTTP 응답 바디에 그대로 쓰라는 뜻
객체를 반환하면 JSON으로 자동 변환하여 응답한다. (Jackson 등 사용)

// @Controller + @ResponseBody 조합 사용 시
@Controller
public class MyController {

    @GetMapping("/data")
    @ResponseBody
    public Map<String, String> getData() {
        return Map.of("message", "hello");
    }
}

// @RestController는 위와 동일한 역할을 자동으로 처리
// @RestController 사용 시
@RestController
public class ApiController {

    @GetMapping("/data")
    public Map<String, String> getData() {
        return Map.of("message", "hello");
    }
}

사용시점

상황사용 어노테이션
HTML 뷰를 반환해야 할 때@Controller
JSON/XML 데이터를 반환해야 할 때@RestController

💙 Spring에서 REST 구현 방식

구성 요소설명
@RestControllerREST API를 처리하는 컨트롤러. 모든 메서드는 데이터(JSON/XML)를 반환
@RequestMapping, @GetMapping, @PostMappingHTTP 메서드(GET, POST, PUT, DELETE 등)에 따른 요청 매핑
@PathVariableURL 경로에 포함된 변수 값 추출
@RequestParam쿼리 파라미터 추출
@RequestBodyHTTP 요청 본문에서 JSON 데이터를 객체로 매핑
@ResponseEntity응답 상태 코드, 헤더, 바디를 명시적으로 제어 가능




🤍 회고

오늘은 Spring에서 Ajax와 REST에 대해 공부했다.
최근 채용 공고에서 "REST 기반 설계 경험"이라는 조건을 보고 궁금했는데, 오늘 학습을 통해 개념을 이해할 수 있었다.
RESTful API는 일관성, 유지보수성, 확장성, 표준화된 통신 등 다양한 이점을 제공한다고 한다.

개념적으로는 이해했지만, 아직 직접 적용해보지 않아서 실무에서 언제 어떻게 사용하는지, 어떤 기준으로 사용해야 하는지는 명확하게 와닿지 않는다.
공부 중에 본 예제들은 대부분 @Controller와 @RestController를 서로 다른 클래스에 나누어 사용하는 방식이었다.
데이터를 반환할 때는 @RestController를 사용한다고는 하지만, 실제 프로젝트에서 컨트롤러를 그렇게 명확하게 나눌 수 있을지 의문이 들었다.

검색으로도 명확한 답을 찾기 어려워 챗GPT에게 질문했고, 아래는 그에 대한 답변이다.

▶ 동일한 컨트롤러에서 일부는 뷰를 반환하고, 일부는 JSON/XML 데이터를 반환하는 경우

@Controller를 기본으로 사용하면서, 데이터를 반환해야 하는 메서드에만 @ResponseBody를 붙이는 방식

  1. 같은 컨트롤러에서 뷰와 JSON을 모두 반환해야 할 경우
@Controller
@RequestMapping("/user")
public class UserController {

    // ✅ 뷰 반환
    @GetMapping("/profile")
    public String userProfile(Model model) {
        model.addAttribute("name", "홍길동");
        return "user/profile"; // JSP 등으로 렌더링
    }

    // ✅ JSON 반환 (일부 메서드만)
    @GetMapping("/data")
    @ResponseBody
    public Map<String, Object> getUserData() {
        return Map.of("id", 1, "name", "홍길동");
    }
}
  1. JSON을 자주 반환한다면 아예 @RestController를 쓰고, 뷰는 RedirectViewResponseEntity<String> 등으로 처리

// @RestController + RedirectView 로 뷰 이동
@RestController
@RequestMapping("/rest")
public class RestExampleController {

    // JSON 응답
    @GetMapping("/data")
    public Map<String, String> getData() {
        return Map.of("message", "Hello, world!");
    }

    // 브라우저에서 페이지 이동 시도
    @GetMapping("/go-to-page")
    public RedirectView redirectToPage() {
        return new RedirectView("/page/main");
    }
}
 
// @RestController + ResponseEntity<String> 로 HTML 직접 반환
@RestController
@RequestMapping("/rest")
public class RestHtmlController {

    @GetMapping("/html")
    public ResponseEntity<String> getHtmlPage() {
        String html = """
            <html>
              <body>
                <h1>Hello from REST!</h1>
              </body>
            </html>
        """;

        return ResponseEntity.ok()
                .header("Content-Type", "text/html; charset=UTF-8")
                .body(html);
    }
}

뷰 중심이 많다면 @Controller + @ResponseBody 구조가 일반적

profile
친애하는 개발자

0개의 댓글