본문 바로가기
Java/Spring

[Spring boot] HTTP API 만들기 - Hello World!

by 평범한 개발자... 2021. 10. 7.

Spring boot로 HTTP API를 만들기 전에, MVC 구조로 웹 애플리케이션이 어떠한 원리로 만들어지고 동작하는지 이해가 필요합니다.

이번 글에서는 간단한 API 1개와 웹페이지 1개를 만들어보고, 그 차이와 원리에 대해서 설명해보겠습니다.

1. 프로젝트 생성

인텔리제이를 기준으로 진행합니다.

[프로젝트 환경]

  • Gradle
  • Java 1.8
  • Spring Boot 2.5.5

[Dependencies]

  • Spring Boot DevTools
    • 자동 재시작 기능 사용
  • Spring Web
    • 내장 톰캣, 웹, MVC, RESTful 등 대다수 기능 포함
  • Thymeleaf
    • 웹 개발을 위한 서버사이드 자바 템플릿 엔진
    • API를 개발하는데 필요하지 않지만, 원리를 설명하고 비교하기 위함.

인텔리제이 얼티메이트 버전을 사용하시는 분들은 툴에 내장된 Spring Initalizr를 이용하여 프로젝트를 생성하면 되고,

커뮤니케이션 버전을 사용하시는 분들은, https://start.spring.io 에 접속하셔서 아래와 같이 설정 후, 프로젝트를 다운받아 압축해제하여 인텔리제이로 Import하면 됩니다.

2. Controller 생성

하위에 controller 패키지를 생성 하고 APIController.java, WebController.java 파일을 만듭니다.

APIController.java 작성

@Controller
public class APIController {

    @ResponseBody
    @GetMapping("/api/hello")
    public String api(){
        return "Hello World!";
    }
}

WebController.java 작성

@Controller
public class WebController {

    @GetMapping("/web/hello")
    public String web(Model model){
        model.addAttribute("msg","Hello World!");
        return "/hello";
    }
}

프로젝트 resources/templates 폴더에 hello.html 파일을 하나 생성합니다.

hello.html 작성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
[[ ${msg} ]]
</body>
</html>

3. 실행

실행 후 크롬창을 열고 아래 각각 URL에 접속해봅니다.

  • localhost:8080/api/hello

  • localhost:8080/web/hello

크롬 개발자 도구 확인

F12을 눌러 개발자 도구를 연다음 Network 탭으로 들어갑니다.
그 다음 새로고침을 눌러서 한번 더 요청해봅니다. 해당 요청의 Response 탭으로 이동하면 서버로 부터 어떤 응답을 받았는지 확인할 수 있습니다.

  • localhost:8080/api/hello

  • localhost:8080/web/hello

차이점 및 원리

코드상의 공통점은

  • 둘 다 @Controller 어노테이션을 사용하였고

차이점은

  • /api/hello의 경우 @ResponseBody 어노테이션이 붙어있고 Hello World! 문자열을 반환합니다.
  • /web/hello의 경우 Hello World! 값을 Model 속성에 넣고, /hello 경로를 반환합니다.

Spring Boot를 Thymeleaf와 같은 템플릿 엔진을 이용하여 웹 애플리케이션을 개발하는 경우, 후자와 같이 컨트롤러 요청이 왔을 때, 템플릿 경로를 반환하게 됩니다.

그러면 ViewResolver를 통해 해당 템플릿을 찾아가서 문법을 해석하고 값을 바인딩 한 뒤, 최종적으로 html 코드 형태로 응답합니다.

반대로 뷰 페이지가 아닌 특정 값을 반환하려면 전자와 같이 @ResponseBody 어노테이션을 이용합니다. 이 경우에는 보통 ajax 요청에 대한 처리를 위해 사용합니다.

Spring MVC 구조 및 ViewResolver 와 HttpMessageConverters

출처: https://www.javatpoint.com/spring-mvc-tutorial

Spring MVC 대략적인 흐름입니다. 해당 글에서 자세히 살펴볼 부분은 5번에 해당합니다.
앞서 말씀드렸다 싶이, 컨트롤러 요청이 오면 ViewResolver를 통해 템플릿을 해석한 후 view를 반환해 줍니다.

하지만, @ResponseBody를 사용하게 되면 어떻게 동작할까요?

Spring에서는 @ResponseBody 어노테이션을 사용하면 ViewResolver가 아닌 HttpMessageConverters에 뷰랜더링을 위임합니다.

HttpMessageConverters는 다양한 포맷의 데이터를 http 메시지에 알맞게 변환시켜주는 역할을 합니다. Spring에서는 컨버터를 데이터 종류에 따라서 자동으로 선택합니다.

대표적인 HttpMessageConverters 중 하나는 MappingJackson2HttpMessageConverter 이고, 자바 및 HashMap 객체를 Json으로 변환하거나 Json 데이터를 자바,HashMap 객체로 변환시켜줍니다.

  • request => json 데이터를 자바 객체로 변환 (json read)
  • response => 자바 객체 데이터를 json 데이터로 변환 (json write)

[번외]
@RestController 라는 어노테이션이 있습니다.
@Controller + @ResponseBody를 합친 어노테이션이며, 해당 컨트롤러로 들어오는 요청에 대한 응답에 대해 @ResponseBody 가 적용됩니다.

HttpMessageConverters 종류

HttpMessageConverters을 상속받아서 구현된 컨버터는 아래 문서에서 확인할 수 있습니다.
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/HttpMessageConverter.html

종류가 굉장히 많은데, 이름만 읽어도 대략 어떤역할을 하는 컨버터인지 알수있습니다. 해당 컨버터로 이동하면 아래와 같이 간략한 설명이 있으니, 참고하시면 되겠습니다.

결론

Hello World! 문자열을 반환하는 API 1개와 Hello World!가 적혀있는 웹페이지 1개를 만들어보았습니다.

API는 @ReponseBody 어노테이션을 이용하여 HttpMessageConverters를 통해 String 형태의 문자열을 반환하였고, 웹페이지는 Thymeleaf라는 템플릿 엔진을 이용하여 ViewResolver를 통해 html이 반환되었습니다.

다음 글에서는 Content-type을 다루도록 하겠습니다.

반응형

'Java > Spring' 카테고리의 다른 글

spring boot h2 memtestdb not found 문제  (0) 2020.07.13

댓글