스프링 부트로 개발하는 MSA 컴포넌트 3 (책정리)

YongHyun·2023년 1월 16일
0
post-thumbnail

스프링 웹 MVC 개요

스프링 프레임워크는 웹 애플리케이션 개발에 필요한 기능들을 담은 spring-webmvc 모듈을 제공한다.
이 모듈의 이름을 따서 스프링 웹 MVC 또는 스프링 MVC 등으로 불린다.
모든 웹 애플리케이션은 HTTP 프로토콜을 사용하기 때문에 HTTP 가 무엇인지 먼저 정리해보았다.

1. HTTP 프로토콜

HTTP는 HyperText Transfer Protocol의 약자로 서버와 클라이언트 사이에 데이터를 전송하는 표준 스펙을 정의한 것이다.
프로토콜은 컴퓨터 간의 통신을 하기 위한 약속이라고 생각하면 된다.

서버 : 데이터를 제공하거나 기능을 처리하는 역할
클라이언트 : 데이터 혹은 기능을 요청하는 역할

이렇게 서버와 데이터는 메시지 형태로 요청하고 응답하는 구조를 가지고 있다.
클라이이언트가 서버에게 요청할때 요청 메시지(request message)를 보내고
서버는 클라이언트에게 데이터를 보낼때 응답 메시지(response message)를 보낸다.

HTTP 메시지 구조

- 출처 : 모든 개발자를 위한 HTTP 웹 기본 지식 (인프런 강의) -

예시

GET /hotel.html?id=129 HTTP/1.1 
- 클라이언트가 서버에서 리소스의 데이터를 받아 오는 것을 요청한다. 	 (GET)
- /hotel.html 리소스에 HTTP 파라미터 이름은 'id'이며 값은 129이다. (/hotel.html?id=129)
- HTTP 프로토콜 버전은 1.1 이다.								 (HTTP/1.1)
HTTP/1.1 200 OK
- 프로토콜 버전은 1.1 이다.						(HTTP/1.1)
- 서버가 클라이언트에게 성공적으로 응답함을 의미함 	(200 OK) 

HTTP 상태 코드를 대분류하면
1XX : 임시 응답을 의미하며, 현 상태의 정보를 응답하는데 사용
2XX : 클라이언트 요청도 성공적으로 받았으며, 프로레스도 정상적으로 처리했을음 의미함.
3XX : 클라이언트가 요청한 리소스가 다른 위치로 옯겨져 클라이언트가 새로운 리소스를 다시 요청해야 하는 경우
4XX : 클라이언트가 전송한 요청 메시지에 에러가 있을음 의미함.
5XX : 클라이언트가 전송한 요청을 처리하는 도중 서버가 에러를 발생했음을 의미

HTTP 특징

HTTP는 비연결성, 무상태 두가지 특성을 가지고 있다.

비연결성 : HTTP 프로토콜이 서버와 클라이언트 사이에 커넥션을 유지할 필요 없이 데이터를 송수신할 수 있음을 의미한다.

  • 장점 : 커넥션을 항상 유지하지 않아도 된다.
  • 단점 : 클라이언트가 서버와 통신을 하려면 커넥션을 매번 새로 맺어여 하는데 이때 비용이 발생함

무상태 : 클라이언트가 서버에 여러 요청을 해도 각 요청은 하나씩 독립적으로 처리된다.

  • 장점 : 이전 요청에 의존하지 않기 때문에 서버 사이에 데이터를 공유하지 않아도 된다.
  • 단점 : 클라이언트가 추가적으로 데이터를 제공해야함

2. 스프링 웹 MVC 프레임워크

스프링 프레임워크는 '로드존슨'이 'J2EE(Java platform, Enterprise Edition)설계 및 개발' 이라는 책의 예제코드를 발전시킨 것이다.

J2EE는 Java API를 제공하면서 동시에 애플리케이션을 만들 때 필요한 여러 스펙을 포함하고 있다.

스프링 웹 MVC 프레임워크도 J2EE 표준인 서블릿을 포함하고 있으며 WAS를 이용하여야 한다.

서블릿(servlet) : HTTP 프로토콜을 사용하여 데이터를 주고받는 서버용 프로그래밍 스펙으로
Servlet 인터페이스 형태로 되어 있으며 이를 구현한 서블릿 애플리케이션들을 관리하고 실행하는 서버를 서블릿 컨테이너 또는 WAS라고 한다. 대표적인 WAS는 톰캣(Tomcat), 제티(Jetty), 언더토우(Undertow)등이 있다.

스프링 웹 MVC 프레임워크는 MVC 패턴으로 구현된 구조입니다.
MVC 패턴은 크게 모델(Model), 뷰(View), 컨트롤러(Controller) 세가지로 역할에 따라 분류한다.
이렇게 역할을 나누면 코드의 복잡도를 줄일 수 있어 변화에 쉽게 대응할 수 있다는 장점을 가지고 있다.

Controller : 사용자 요청을 가장 먼저 어떻게 처리할지 결정하며 적절한 Model이나 요청에 적합한 View에 전달하는 역할을 한다.
Model : 컨트롤러에서 전달받은 사용자 요청 데이터를 가공하거나 데이터 저장소에 데이터를 처리하는 역할을 한다.
View : 사용자에게 응답하는 화면을 담당한다.

스프링 MVC 프레임워크는 의존성 문제를 해결하기 위해 IoC 컨테이너를 제공한다. 그래서 스프링 개발자는 스테레오 타입 애너테이션(@Controller, @Service, @Component, @Repository)을 정의해서 ApplicationContext에 스프링 빈으로 등록한 후 스프링 MVC 프레임워크를 이용하면 위와 같은 형태가 된다.

여기서 스프링 MVC 프레임워크가 몇가지 주요한 컴포넌트를 제공하는데
HandlerMapping, HandlerAdapter, ModelAndView, ViewResolver, DispatcherServlet 이 있다. 이 중에서 DispatcherServlet이 가장 핵심 역할을 하는 컴포넌트이다.

스프링 MVC 컴포넌트와 동작 순서

출처 : 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (인프런 강의 자료 중) -

위 그림의 순서를 정리하면

  1. 클라이언트에서 전송된 모든 HTTP 요청 메시지는 가장 먼저 DispatcherServlet이 받아 처리한다.

    DispatcherServlet : 프론트 컨트롤러 패턴으로 디자인되어 있으며 사용자의 모든 요청을 받고 이 요청을 분석한 후 적절한 컴포넌트로 전달하는 역할을 한다.

  2. DispatcherServlet은 요청 메시지의 요청 라인과 헤더들을 파악한 후 어떤 컨트롤러 클래스의 어떤 메서드로 전달할지 HandlerMapping 컴포넌트의 메서드를 사용하여 확인한다.

    HandlerMapping : servlet.HandlerMapping 인터페이스를 구현한 컴포넌트로 HTTP 요청 메시지를 추상화한 HttpServletRequest 객체를 받아 사용자 요청을 처리하는 핸들러 객체를 조회하는 getHandler() 메서드를 제공한다.

  3. DispatcherServlet은 사용자 요청을 처리하기에 적합한 컨트롤러 클래스에 HTTP 요청 메시지를 전달하기 위해 전달 역할을 하는 HandlerAdapter에 전달한다.

    HandlerAdapter : servlet.HandlerAdapter 인터페이스를 구현한 컴포넌트이다. 이 컴포넌트는 사용자의 요청과 응답을 추상화한 HttpServletRequest, HttpServletResponse 객체를 컨트롤러 클래스의 메서드에 전달하는 오브젝트 어뎁터 역할을 한다.

  4. HandlerAdapter는 해당 컨트롤러 클래스에 클라이언트 요청을 전달한다.

  5. 컨트롤러 클래스는 비즈니스 로직을 실행한 후 결과를 다시 컨트롤러 클래스에 전달하고 어떤 뷰로 전달할지 결정한다.

  6. HandlerAdapter는 처리할 뷰와 뷰에 매핑할 데이터를 ModelAndView 객체에 포함하여 DispatcherServlet에 전달한다.

    ModelAndView : 컨트롤러 클래스에 처리한 결과를 어떤 뷰에서 처리할지 결정하고 뷰에 전달할 데이터를 포함하는 클래스이다.

  7. DispatcherServlet은 처리할 뷰 정보를 ViewResolver에 확인한다.

    ViewResolver : 문자열 기반의 View 이름을 실제 View 구현체로 변경한다. 다양한 템플릿 뷰 엔진이 있으며, 각각에 적합한 ViewResolver 구현체는 스프링 프레임워크에서 제공한다.
    예) FreemarkerViewResolver, thymeleafViewResolver

  8. DispatcherServlet은 View에 데이터를 전달하고, View는 데이터를 HTML, XML 등 적합한 포멧으로 변환한다. 그리고 변환한 데이터를 DispatcherServlet으로 전달한다.

  9. DispatcherServlet은 최종적으로 변환된 데이터를 클라이언트에 전달한다.

3. REST-API 설계

REST는 Representational State Transfer의 약자로 자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 것을 의미한다.

API는 Application Programming Interface의 약자로 운영체제와 응용프로그램 사이의 통신에 사용되는 언어나 메시지 형식을 뜻한다.

음식점을 예시로 들면 손님은 음식을 주문하기 위해서 어떠한 메뉴가 있는지 메뉴판을 확인한다. 그러면 요리사는 메뉴를 확인하고 음식을 만든다. 이때 중간 손님과 요리사 사이의 중간 역할을 하는 메뉴판이 API가 하는 역할과 같다고 생각하면 된다.

REST-API는 HTTP 프로토콜을 사용하는 API이다. HTTP 프로토콜을 사용하기 때문에 그 특징인 무상태성 또한 그대로 가지고 있다. 또한 설계하는데 일관성, 멱등성 세 가지 특성을 가져야 한다.

  • 무상태성 : 클라이언트는 서버와 커넥션을 맺고 요청을 하고 응답을 받은 후 커넥션을 끊는다. 이러한 무상태성 덕분에 서비스 도중에도 매우 쉽게 서버를 증설하거나 축소할 수 있고, 배포하기도 쉬어진다.
  • 일관성 : API를 설계할 때 같은 형태의 응답 메시지나 일관된 규칙으로 만들어진 HTTP 상태 코드를 정의해야 한다. 이러한 일관성 특성 덕분에 어떠한 정보를 리턴할지 예측하기가 쉬어진다.
  • 멱등성 : 클라이언트가 서버로 동일한 API를 여러 번 호출한 결과가 한 번만 요청한 결과와 같아야 한다는 특성이다.
    HTTP 메서드에 대입하면 리소스 상태를 변경하지 않는 GET메서드와 PUT, DELETE 같은 변경하는 메서드는 멱등성이 있어야 한다. POST는 호출한 횟수만큼 데이터를 만들면 되기 때문에 멱등성을 가질 필요는 없다.

REST-API 세가지 요소

  • 리소스 : 리소스(자원)는 HTTP URI로 표현한다.
  • 행위 : 리소스에 대한 행위는 HTTP 메서드로 표현한다. 일반적으로 리소스를 생성하고 값을 조회, 수정, 삭제하는 행위 등을 표현할 수 있다.
  • 표현 : 리소스에 대한 행위 내용은 HTTP 메시지 내용으로 표현한다. HTTP 메시지의 포맷은 JSON을 사용한다.

REST-API 기본 규칙

  • 리소스 이름은 동사보다는 명사를 사용
  • 리소스는 계층 관계를 가지므르 복수 형태를 사용
  • 리소스에 대한 행위는 GET, POST, PUT, DELETE를 기본으로 사용

REST-API에서 사용하는 메서드

  • GET : 리소스 정보를 조회하는 데 사용
  • POST : 클라이언트가 HTTP 메시지 바디에 전송한 데이터를 정의된 리소스에 생성
  • PUT : 정의된 리소스 객체를 HTTP 메시지 바디에 전송한 데이터로 전체 수정
  • DELETE : 정의된 리소스를 삭제
  • PATCH : 정의된 리소스의 일부 데이터를 수정

호텔들의 정보를 조회, 등록하는 REST-API 호텔 데이터를 만들어야 한다고 예시를 들면

호텔 데이터 리소스는 '/hotels' 로 복수형으로 정의한다.

특정 호텔의 리소스를 정의할 때는 '/hotels/{uniqueId}' 
처럼 hotels 하위에 고유한 아이디 값을 사용하여 정의하는 것이 유리하다.

객실 정보 리소스도 처리해야 한다면 
호텔 아이디는 9281726, 객실 아이디는 west-901
'/hotels/9281726/rooms/west-901'로 정의하면 된다.
* 호텔 아이디와 객실 아이디 모두 각 각 고유한 값으로 설계하는 것을 추천
 그래서 데이터베이스 기본 키를 활용 함*

4. 간단한 REST-API 예제

@ResponseBody 애너테이션을 정의한 getHotelById 메서드는 ResponseEntity< Hotel 객체를 JSON 형식으로 변경해주는 역할을 한다.
이때 리턴한 객체는 스프링에 있는 메시지 컨버터(HttpMessageConverter)중 적합한 메시지 컨버터가 JSON 메시지로 변환시켜주는 역할을 한다.

ResponseEntity 클래스는 HTTP 헤더와 상태 코드, 바디 메시지를 포함하는 HTTP 응답 메시지를 추상화한 것이다.

위의 예제를 Postman 프로그램을 통해서 호출해 보면

profile
백엔드 개발자 되기 위한 여정

0개의 댓글