스프링 입문 - API
이번에는 API 방식에 대해서 알아보자.
사실, 정적 컨텐츠 방식을 제외하면,
앞서 살펴보았던 MVC방식처럼 View를 찾아서 template engine을 통해서 화면을 랜더링하고, html로 변환해서 웹브라우저에 넘겨주는 방식이 있고,
그다음 방법이 API를 사용하는 방법이 있다.
그러니까, 정적 컨텐츠 방식을 제외하면,
2가지 방법만 기억하면 된다.
MVC방식처럼 HTML로 내리냐,
아니면 API라는 방식으로 데이터를 바로 내리냐의 차이이다.
HelloController에 추가코드를 작성해 보자.
@ResponseBody는 HTML에 나오는 body태그를 이야기 하는게 아니라,
http 통신 프로토콜에서 header부와 body부가 있는데,
body부에 return으로 준 "hello " +name; 을 직접 넣어주겠다.라는 의미이다.(body부에 직접 넣어주겠다는 의미)
만약에 name을 spring으로 주면, return "hello spring" 으로 바뀔 것이다.
즉, 이 문자가, 내가 요청한 클라이언트에 그대로 내려간다.
이 방식과 template engine방식의 차이는,
view같은게 없이, 그냥 해당 문자가 그대로 내려간다는 것이다.
한번 서버를 돌려서 접속해보자.
"http://localhost:8080/hello-string?name=spring!"
소스보기를 해보자.
HTML 태그가 하나도 없이,
내가 적은 문자가 그대로 내려갔다.
이전에 살펴본 template engine은 view라는 템플릿이 있는 상황에서 그것을 조작하는 방식이고,
@ResponseBody 방식은,
데이터를 그대로 내려준다.
이렇게 @ResponseBody 문자를 반환하는 예제를 보았다.
이번에는 @ResponseBody 객체 반환을 해보자.
만약에 문자가 아니라, 데이터를 반환해야하는 상황 때문에 API방식을 많이 사용한다.
@GetMapping("hello-api") 를 만들어보자.
Hello 클래스를 생성해주었고, generate를 이용해서 getter와 setter 메서드를 만들어 주었다.
그리고, Hello객체를 만들고, hello.setName(name)으로 파라미터에서 넘어온 name을 넣어주었다.
그리고 return hello; 로 객체를 반환하도록 했다.
getter, setter는 cdm+N을 눌러서 선택하고, OK누르면 된다.
getter, setter는 get, set이 만들어지는데,
Java Bean 규약 이라고 한다.
이렇게 해두면,
private String name; 은 private이므로 외부에서 바로 못꺼내는 것을
라이브러리같은데서 사용하거나, 내가 쓸때는,
get, set같은 메서드를 통해서 private String name; 에 접근한다.
get, set을 public으로 열어 놓은 것이다.
이것을 Java Bean 표준 방식이라고 한다.
그리고 위의 getter, setter 방식을 프로퍼티 접근 방식이라고 하기도 한다.
서버를 돌려서 확인해보자.
"http://localhost:8080/hello-api?name=spring!"
그리고 소스보기를 해보자.
이것은 json 방식이라고 한다.
json은 key,value로 이루어진 구조이다.
위예시에서는 key가 name, value가 url로 넣었던 spring! 이다.
이러한 것을 json이라고 한다.
과거에는 xml방식도 많이 쓰였다. html태그가 xml방식으로 쓴 것이다.
xml방식은 <HTML> </HTML> 처럼 열고 닫고를 두번씩 해야하는데,
JSON은 key, value로 되어있어서 심플하다.
최근에는 거의 JSON방식으로 통일 되었다.
Spring도 기본적으로, 객체를 반환하면서 @ResponseBody라고 해놓으면,
JSON방식으로 반환하는 것이 기본이다.
그래서 최근에 프로젝트를 진행하면, JSON방식으로 진행하면 된다.
이번에는 간단한 그림을 통해
@ResponseBody 를 사용했을 때의 동작 과정을 정리해보자.
먼저, locallhost:8080/hello-api를 요청하면,
톰켓 내장서버에서 "hello-api가 요청으로 왔어!" 라고 스프링에 던진다.
스프링은, 여기보니까 "hello-api가 있네?" 라고 하는데,
"어? 근데 @ResponseBody라는 애너테이션이 붙어있네?"라고 한다.
원래, 이런게 안붙어 있으면, 이전에 살펴본 템플릿 엔진 처럼 viewResolver한테 던지면서 "나한테 맞는 template 찾아서 돌려줘" 라고 하는데,
@ResponseBody 가 붙어있으면,
"http응답에 그대로 데이터를 넘겨야 되겠구나!" 라고 동작을 한다.
그런데, 보니까 hello가 문자가 아니라 객체다.
문자의 경우에는 문자값을 그대로 http응답에 넣어서 주고 끝이었는데,
객체를 줘야하므로 스프링이 생각을 한다. "객체를 줘야하는데?"
스프링에서는 이것을 어떻게 할지 디폴트 값이 정해져 있다.
"객체가 오면, 기본 디폴트로, JSON 방식으로 데이터를 만들어서 http응답에 반환하겠다" 라는게 스프링의 기본 정책이다.
즉, @ResponseBody라고 오면서 hello 객체를 넘기면,
몇가지 조건을 보는데,
우선, @ResponseBody가 있으면, HttpMessageConverter라는 애가 동작을 한다.
그리고, 반환하는게 단순히 문자이면, StringConverter라는게 동작을 한다.
그런데 반환하는게 객체이면, JsonConverter라는 것이 동작을 한다.
그러면서 객체를 JSON 스타일로 바꾼다. (hello 객체를 JSON 스타일로 바꾼다. "어? key로 name이 있고 value로 값이 있네?" 라고 하며..)
그러면서 JsonConverter는 JSON 스타일로 바꾼 것을 나를 요청한 웹브라우저 or 서버 에게 보내준다.
@ResponseBody를 사용한 API는 이러한 과정으로 동작한다.
참고로,
HTTP 스펙에 보면, 요청을 할 때, "나는 이런 포맷으로 받고 싶어" 라는 것이 있는데,
그것이 Acept와 헤더라는 것인데,
거기에서 JSON이라고 요청이 오면, JSON으로 받고,
거기에서 아무것도 안보내면, "다받을 수 있어!" 라는 것으로 간주되어,
스프링이 알아서 현재 있는 것으로 보낸다.
그런데, 만약에 "나는 꼭 XML로 받을거야!"라거나 "나는 꼭 특정 포맷으로 받아야해!!" 라고 하면,
이때 해당 메시지(포맷)의 컨버터가 동작하는 것이다.
그래서 위 예제에서는 hello 객체를 넘겼는데,
만약에 요청을 할 때 xml을 요청하면, xml라이브러리를 사용하는 등의 작업을 추가하면, XmlMessageConverter가 동작해서 xml로 반환받을 수 있다.
즉, 클라이언트의 HTTP Accept 헤더와 서버의 컨트롤러 반환 타입 정보 둘을 조합해서 메시지 컨버터가 선택된다.
요즈음에는 보통 JSON을 쓴다!! 최근 트렌드는, 객체를 JSON으로 반환 해준다 라고 이해하고 있으면 된다.
'Spring' 카테고리의 다른 글
스프링 입문 - 회원 도메인과 리포지토리 만들기 (0) | 2022.05.17 |
---|---|
스프링 입문 - 비즈니스 요구사항 정리 (0) | 2022.05.17 |
스프링 입문 - MVC와 템플릿 엔진 (0) | 2022.05.16 |
스프링 입문 - 정적 컨텐츠 (0) | 2022.05.16 |
스프링 입문 - 빌드하고 실행하기 (0) | 2022.05.15 |
댓글
이 글 공유하기
다른 글
-
스프링 입문 - 회원 도메인과 리포지토리 만들기
스프링 입문 - 회원 도메인과 리포지토리 만들기
2022.05.17 -
스프링 입문 - 비즈니스 요구사항 정리
스프링 입문 - 비즈니스 요구사항 정리
2022.05.17 -
스프링 입문 - MVC와 템플릿 엔진
스프링 입문 - MVC와 템플릿 엔진
2022.05.16 -
스프링 입문 - 정적 컨텐츠
스프링 입문 - 정적 컨텐츠
2022.05.16