Develog
코드스테이츠 41일차 본문
Chapter - Spring MVC 아키텍처
학습목표
- Spring MVC
- Spring MVC란 무엇인지 이해할 수 있다.
- Spring MVC의 동작방식과 구성요소를 이해할 수 있다.
Spring MVC란?
Spring의 모듈 중에는 웹 계층을 담당하는 몇가지 모듈이 있다.
특히 서블릿(Servlet) API를 기반으로 클라이언트의 요청을 처리하는 모듈이 있는데, 이 모듈을 spring-webmvc라고 한다.
MVC를 줄여서 Spring MVC라고 부르고 있고, Spring MVC가 웹 프레임워크의 한 종류이기 때문에 Spring MVC 프레임워크라고도 부른다.
간단하게 정리하자면 Spring MVC는 클라이언트의 요청을 편리하게 처리해주는 프레임워크이다.
서블릿(Servlet)이란?
서블릿은 클라이언트의 요청을 처리하도록 특정 규약에 맞추어서 Java 코드로 작성하는 클래스 파일이다.
아파치 톰캣(Apache Tomcat)은 이러한 서블릿들이 웹 애플리케이션으로 실행이 되도록 해주는 서블릿 컨테이너(Servlet Container) 중 하나이다.
MVC
- Model
- View
- Controller
Model
Spring MVC 기반의 웹 애플리케이션이 클라이언트의 요청을 전달 받으면 요청 사항을 처리하기 위한 작업을 한다.
이렇게 처리한 작업의 결과 데이터를 클라이언트에게 응답으로 돌려줘야하는데, 이 때 클라이언트에게 응답으로 돌려주는 작업의 처리 결과 데이터를 Model이라고 한다.
클라이언트의 요청 사항을 구체적으로 처리하는 영역을 서비스 계층(Service Layer)이라고 하며, 실제로 요청 사항을 처리하기 위해 Java 코드로 구현한 것을 비즈니스 로직(Business Logic)이라고 한다.
View
View는 앞에서 설명한 Model 데이터를 이용해서 웹브라우저 같은 클라이언트 애플리케이션의 화면에 보여지는 리소스(Resource)를 제공하는 역할을 한다.
View의 형태는 아래와 같이 나눌 수 있다.
HTML 페이지의 출력
- 클라이언트 애플리케이션에 보여지는 HTML 페이지를 직접 렌더링해서 클라이언트 측에 전송하는 방식이다.
- 즉, 기본적인 HTML 태그로 구성된 페이지에 Model 데이터를 채워 넣은 후, 최종적인 HTML 페이지를 만들어서 클라이언트 측에 전송해준다.
- Spring MVC에서 지원하는 HTML 페이지 출력 기술에는 Thymeleaf, FreeMarker, JSP + JSTL, Tiles 등이 있다.
PDF, Excel 등의 문서 형태로 출력
- Model 데이터를 가공해서 PDF 문서나 Excel 문서를 만들어서 클라이언트 측에 전송하는 방식이다.
- 문서 내에서 데이터가 동적으로 변경되어야 하는 경우 사용할 수 있는 방식이다.
XML, JSON 등 특정 형식의 포맷으로의 변환
- Model 데이터를 특정 프로토콜 형태로 변환해서 변환된 데이터를 클라이언트 측에 전송하는 방식이다.
- 이 방식의 경우 특정 형식의 데이터만 전송하고, 프런트엔드 측에서 이 데이터를 기반으로 HTML 페이지를 만드는 방식이다.
- 장점
- 프런트엔드 영역과 백엔드 영역이 명확하게 구분되므로 개발 및 유지보수가 상대적으로 용이하다.
- 프런트엔드 측에서 비동기 클라이언트 애플리케이션을 만드는 것이 가능해진다.
JSON(JavaScript Object Notation)이란?
JSON은 Spring MVC에서 클라이언트 애플리케이션과 서버 애플리케이션이 주고 받는 데이터 형식이다.
과거에는 XML 형식의 데이터가 많이 사용되었으나 현재는 XML보다 상대적으로 가볍고, 복잡하지 않은 JSON 형식을 대부분 사용하고 있는 추세이다.
- JSON의 기본 포맷
- {”속성”:”값”} 형태
Controller
Controller는 클라이언트 측의 요청을 직접적으로 전달 받는 엔드포인트(Endpoint)로써 Model과 View의 중간에서 상호 작용을 해주는 역할을 한다.
즉, 클라이언트 측의 요청을 전달 받아서 비즈니스 로직을 거친 후에 Model 데이터가 만들어지면, 이 Model 데이터를 View로 전달하는 역할을 한다.
Model, View, Controller 간의 처리 흐름
Client가 요청 데이터 전송
→ Controller가 요청 데이터 수신 → 비즈니스 로직 처리 → Model 데이터 생성
→ Controller에게 Model 데이터 전달 → Controller가 View에게 Model 데이터 전달
→ View가 응답 데이터 생성
총정리
- Spring의 모듈 중에서 서블릿(Servlet) API를 기반으로 클라이언트의 요청을 처리하는 모듈이 바로 spring-webmvc 이다.
- spring-webmvc 모듈이 Spring MVC이다.
- Spring MVC는 웹 프레임워크의 한 종류이기 때문에 Spring MVC 프레임워크라고도 부른다.
- Spring MVC에서 M은 Model을 의미한다.
- 클라이언트에게 응답으로 돌려주는 작업의 처리 결과 데이터를 Model이라고 한다.
- Spring MVC에서 V는 View를 의미한다.
- View는 Model 데이터를 이용해서 웹브라우저 같은 클라이언트 애플리케이션의 화면에 보여지는 리소스(Resource)를 제공한다.
- 우리가 실질적으로 학습하게 되는 View는 JSON 포맷의 데이터를 생성한다.
- Spring MVC에서 C는 Controller를 의미한다.
- Controller는 클라이언트 측의 요청을 전달 받아 Model과 View의 중간에서 상호 작용을 해주는 역할을 담당한다.
- Spring MVC에서 MVC의 전체적인 동작 흐름은 다음과 같다.
- Client가 요청 데이터 전송 → Controller가 요청 데이터 수신 → 비즈니스 로직 처리 → Model 데이터 생성 → Controller에게 Model 데이터 전달 → Controller가 View에게 Model 데이터 전달 → View가 응답 데이터 생성
Spring MVC의 동작 방식과 구성 요소
(1) 먼저 클라이언트가 요청을 전송하면 DispatcherServlet이라는 클래스에 요청이 전달된다.
(2) DispatcherServlet은 클라이언트의 요청을 처리할 Controller에 대한 검색을 HandlerMapping 인터페이스에게 요청한다.
(3) HandlerMapping은 클라이언트 요청과 매핑되는 Controller 정보를 다시 DispatcherServlet에게 리턴해준다.
Controller 정보에는 해당 Controller안에 있는 Handler 메서드 정보를 포함하고 있다.
Handler 메서드는 Controller 클래스 안에 구현된 요청 처리 메서드를 의미한다.
(4) 요청을 처리할 Controller 클래스를 찾았으니 이제는 실제로 클라이언트 요청을 처리할 Handler 메서드를 찾아서 호출해야 한다.
DispatcherServlet은 Handler 메서드를 직접 호출하지 않고, HandlerAdpater에게 Handler 메서드 호출을 위임한다.
(5) HandlerAdapter는 DispatcherServlet으로부터 전달 받은 Controller 정보를 기반으로 해당 Controller의 Handler 메서드를 호출한다.
(6) Controller의 Handler 메서드는 비즈니스 로직 처리 후 리턴 받은 Model 데이터를 HandlerAdapter에게 전달한다.
(7) HandlerAdapter는 전달받은 Model 데이터와 View 정보를 다시 DispatcherServlet에게 전달한다.
(8) DispatcherServlet은 전달 받은 View 정보를 다시 ViewResolver에게 전달해서 View 검색을 요청한다.
(9) ViewResolver는 View 정보에 해당하는 View를 찾아서 View를 다시 리턴해줍니다.
(10) DispatcherServlet은 ViewResolver로부터 전달 받은 View 객체를 통해 Model 데이터를 넘겨주면서 클라이언트에게 전달할 응답 데이터 생성을 요청한다.
(11) View는 응답 데이터를 생성해서 다시 DispatcherServlet에게 전달한다.
(12) DispatcherServlet은 View로부터 전달 받은 응답 데이터를 최종적으로 클라이언트에게 전달한다.
DispatcherServlet의 역할
클라이언트로부터 요청을 전달 받으면 HandlerMapping, HandlerAdapter, ViewResolver, View 등 대부분의 Spring MVC 구성 요소들과 상호 작용을 하고 있는 것을 볼 수 있다.
그런데 DispatcherServlet은 굉장히 바빠보이지만 실제로 요청에 대한 처리는 다른 구성 요소들에게 위임(Delegate)하고 있다.
이처럼 DispatcherServlet이 애플리케이션의 가장 앞단에 배치되어 다른 구성요소들과 상호작용하면서 클라이언트의 요청을 처리하는 패턴을 Front Controller Pattern이라고 한다.
총정리
- Spring MVC의 요청 처리 흐름
- 클라이언트의 요청을 제일 먼저 전달 받는 구성요소는 DispatcherServlet이다.
- DispatcherServlet은 HandlerMapping 인터페이스에게 Controller의 검색을 위임한다.
- DispatcherServlet은 검색된 Controller 정보를 토대로 HandlerAdapter 인터페이스에게 Controller 클래스내에 있는 Handler 메서드의 호출을 위임한다.
- HandlerAdapter 인터페이스는 Controller 클래스의 Handler 메서드를 호출한다.
- DispatcherServlet은 ViewResolver에게 View의 검색을 위임한다.
- DispatcherServlet은 View에게 Model 데이터를 포함한 응답 데이터 생성을 위임한다.
- DispatcherServlet은 최종 응답 데이터를 클라이언트에게 전달한다.
- DispatcherServlet이 애플리케이션의 가장 앞단에 배치되어 다른 구성요소들과 상호작용하면서 클라이언트의 요청을 처리하는 패턴을 Front Controller Pattern이라고 한다.
Chapter - Controller
학습목표
- Controller
- API 엔드 포인트인 Controller의 구성 요소를 이해할 수 있다.
- 실제 동작하는 Controller의 기본 기능을 구현할 수 있다.
Controller 클래스 설계 및 구조 생성
API 계층은 클라이언트의 요청을 직접적으로 전달 받는 계층이다.
클라이언트 요청 흐름의 끝에는 Controller가 있다.
바로 이 Controller 클래스가 Spring MVC에서 클라이언트 요청의 최종 목적지인 셈이다.
애플리케이션을 제작하기 위해서 실질적으로 제일 먼저 해야되는 일은 애플리케이션의 경계를 설정하는 것과 애플리케이션 기능 구현을 위한 요구 사항을 수집하는 일이다.
패키지 구조 생성
Spring Boot 기반의 애플리케이션에서 주로 사용되는 Java 패키지 구조는 기능 기반 패키지 구조(package-by-feature)와 계층 기반 패키지 구조(package-by-layer)가 있다.
기능 기반 패키지 구조(package-by-feature)
기능 기반 패키지 구조란 말 그대로 애플리케이션의 패키지를 애플리케이션에서 구현해야 하는 기능을 기준으로 패키지를 구성하는 것이다.
이렇게 나누어진 패키지 안에는 하나의 기능을 완성하기 위한 계층별(API 계층, 서비스 계층, 데이터 액세스 계층)클래스들이 모여있다.
회원을 관리하기 위한 회원 기능과 커피를 관리하기 위한 커피 기능을 각각 coffee와 member라는 패키지로 나누었으며, 각각의 패키지 안에 레이어 별 클래스들이 존재한다.
계층 기반 패키지 구조(package-by-layer)
계층 기반 패키지 구조란 패키지를 하나의 계층(Layer)으로 보고 클래스들을 계층별로 묶어서 관리하는 구조를 말한다.
위 사진은 계층(Layer)을 기반으로 패키지를 구성한 예입니다. ‘controller, dto’ 패키지는 API 계층에 해당되고, ‘model, service’ 패키지는 비즈니스 계층에 해당되며, repository는 데이터 액세스 계층에 해당한다.
위 두가지 패키지 구조는 애플리케이션의 요구 사항이나 특성에 따라서 상황에 맞게 적절하게 사용하면 된다.
다만, Spring Boot 팀에서는 테스트와 리팩토링이 용이하고, 향후에 마이크로 서비스 시스템으로의 분리가 상대적으로 용이한 기능 기반 패키지 구조 사용을 권장하고 있다.
애플리케이션의 기능 요구 사항
애플리케이션의 Controller 클래스 코드를 작성하기 전에 우리가 생각해 보아야 할 부분은 먼저 ‘클라이언트로부터 발생할 요청에는 어떤 것들이 있을까’를 고민해보는 것이다.
서버 애플리케이션 입장에서 생각하면 ‘클라이언트 요청을 처리할 서버 애플리케이션의 기능으로 뭐가 필요할까’와 같다.
애플리케이션에 필요한 리소스
REST API 기반의 애플리케이션에서는 일반적으로 애플리케이션이 제공해야 될 기능을 리소스(Resource, 자원)로 분류한다.
엔트리포인트(Entrypoint) 클래스 작성
Spring Boot 기반의 애플리케이션이 정상적으로 실행되기 위해서 가장 먼저 해야될 일은 main() 메서드가 포함된 애플리케이션의 엔트리포인트(Entrypoint, 애플리케이션 시작점)를 작성하는 것이다.
참고로 ‘Spring Initializr’를 통해 생성한 프로젝트에는 엔트리포인트 클래스가 이미 작성되어 있다.
@SpringBootApplication 은 코드 상에서는 보이지 않지만 내부적으로 세가지 일을 해준다.
- 자동 구성을 활성화한다.
- 애플리케이션 패키지 내에서 @Component가 붙은 클래스를 검색한 후(scan), Spring Bean으로 등록하는 기능을 활성화한다.
- @Configuration 이 붙은 클래스를 자동으로 찾아주고, 추가적으로 Spring Bean을 등록하는 기능을 활성화한다.
SpringApplication.run(Section3Week1Application.class, args);
Spring 애플리케이션을 부트스트랩하고, 실행하는 역할을 한다.
부트스트랩(Bootstrap)이란?
애플리케이션이 실행되기 전에 여러가지 설정 작업을 수행하여 실행 가능한 애플리케이션으로 만드는 단계를 의미한다.
애플리케이션의 Controller 구조 작성
@RestController
- Spring MVC에서는 특정 클래스에 @RestController 를 추가하면 해당 클래스가 REST API의 리소스(자원, Resource)를 처리하기 위한 API 엔드포인트로 동작함을 정의한다.
- 또한 @RestController 가 추가된 클래스는 애플리케이션 로딩 시, Spring Bean으로 등록해준다.
@RequestMapping
- @RequestMapping 은 클라이언트 요청을 처리하는 핸들러 메서드(Handler Method)를 매핑해주는 역할을 한다.
@RequestMapping 은 Controller 클래스 레벨에 추가하여 클래스 전체에 사용되는 공통 URL(Base URL) 설정을 한다.
총정리
Spring Boot 애플리케이션으로서 동작하기 위한 엔트리포인트에는 @SpringBootApplication을 추가한다.
main() 메서드 내에서 SpringApplication.run()을 호출하면 Spring Boot 기반의 애플리케이션으로 동작한다.
@RestController를 클래스에 추가함으로써 해당 클래스를 REST API의 리소스(자원, Resource)를 처리하기 위한 API 엔드포인트로 동작하게 해준다.
@RequestMapping을 Controller 클래스 레벨에 추가하여 클래스 전체에 사용되는 공통 URL(Base URL)을 설정할 수 있다.
핸들러 메서드(Handler Method)
Controller의 구조만 작성한 상태에서 요청을 전송하면 클라이언트의 요청을 처리할 핸들러 메서드(Handler Method)가 없기 떄문에 404 에러가 발생할 것이다.
핸들러 메서드(Handler Method) 적용
핸들러 메서드를 작성하기 전에 먼저 각 핸들러 메서드에서 필요한 기능별 정보들을 정의한다. 예를 들면 회원 정보, 커피 정보, 주문 정보 등이 있다.
@RequestMapping를 통해 핸들러 메서드를 추가해보자
produces = {MediaType.APPLICATION_JSON_VALUE})
- produces
produces애트리뷰트(Attribute)는 응답 데이터를 어떤 미디어 타입으로 클라이언트에게 전송할 지를 설정한다. JSON 형식의 데이터를 응답 데이터로 전송 하겠다는 의미로 MediaType.APPLICATION_JSON_VALUE 값을 설정할 수 있다. 이 값을 설정하지 않으면 JSON 형식의 데이터를 응답으로 전송하지 않고, 문자열 자체를 전송한다.
@PostMapping 은 클라이언트의 요청 데이터(request body)를 서버에 생성할 때 사용하는 애너테이션이다.
@RequestParam은 핸들러 메서드의 파라미터 종류 중 하나이다.
주로 클라이언트 쪽에서 전송하는 요청 데이터를 쿼리 파라미터(Query Parmeter 또는 Query String), 폼 데이터(form-data), x-www-form-urlencoded 형식으로 전송하면 이를 서버 쪽에서 전달 받을 때 사용하는 애너테이션이다.
@GetMapping은 클라이언트가 서버에 리소스를 조회할 때 사용하는 애너테이션이다.
식별자(Identifier)란?
어떤 데이터를 식별할 수 있는 고유값을 의미한다. (Ex. 데이터베이스의 기본키)
총정리
- 클라이언트의 요청을 전달 받아서 처리하기 위해서는 요청 핸들러 메서드(Request Handler Method)가 필요하다.
- Spring MVC에서는 HTTP Method 유형과 매치되는 @GetMapping, @PostMapping 등의 애너테이션을 지원한다.
- @PathVariable 애너테이션을 사용하면 클라이언트 요청 URI에 패턴 형식으로 지정된 변수의 값을 파라미터로 전달받을 수 있다.
- @RequestParam 애너테이션을 사용하면 쿼리 파라미터(Query Parmeter 또는 Query string), 폼 데이터(form-data), x-www-form-urlencoded 형식의 데이터를 파라미터로 전달 받을 수 있다.
- @GetMapping, @PostMapping 등에서 URI를 생략하면 클래스 레벨의 URI 경로만으로 요청 URI를 구성한다.
핸들러 메서드의 개선사항
(1) JSON 문자열을 개발자가 직접 수작업으로 작성하던 부분을 Map 객체로 대체할 수 있다.
이를 통해 클래스 레벨의 @RequestMapping 의 ‘produces’ 애트리뷰트를 생략할 수 있다.
Map 객체를 리턴하게 되면 내부적으로 ‘이 데이터는 JSON 형식의 응답 데이터로 변환해야 되는구나’라고 이해하고 JSON 형식으로 자동 변환해주기 때문이다.
(2) 리턴 값으로 JSON 문자열을 리턴하던 부분을 ResponseEntity 객체를 리턴하는 것으로 바꿔준다.
ResponseEntity 객체를 생성하면서 생성자 파라미터로 응답 데이터(map)와 HTTP 응답 상태를 함께 전달한다.
이처럼 HTTP 응답 상태를 명시적으로 함께 전달하면 클라이언트의 요청을 서버가 어떻게 처리했는지를 쉽게 알 수 있어 클라이언트 쪽에서는 이 HTTP 응답 상태를 기반으로 정상적으로 다음 처리를 할지 에러 처리를 할지 결정하면 되는 것이다.
정리하자면
- 핸들러 메서드의 리턴 값으로 Map 객체를 리턴하면 Spring MVC 내부적으로 JSON 형식의 데이터를 생성해준다. 즉, 클래스 레벨의 @RequestMapping 에 ‘produces’ 애트리뷰트를 지정할 필요가 없다.
- ResponseEntity 클래스로 응답 데이터를 래핑함으로써 조금 더 세련된 방식으로 응답 데이터를 리턴할 수 있다.
- POST Method 형식의 클라이언트 요청에 대한 응답 상태는 HttpStatus.OK보다는 HttpStatus.CREATED가 조금 더 자연스럽다.
HTTP 헤더(Header)
HTTP 헤더(Header)란?
HTTP 메시지(Messages)의 구성 요소 중 하나로써 클라이언트의 요청이나 서버의 응답에 포함되어 부가적인 정보를 HTTP 메시지에 포함할 수 있도록 해준다.
HTTP 헤더(Header)의 사용 목적은?
1. 클라이언트와 서버의 관점에서 내부적으로 가장 많이 사용되는 헤더 정보로 ‘Content-Type’이 있다.
‘Content-Type’ 헤더 정보는 클라이언트와 서버가 주고 받는 HTTP 메시지 바디(body, 본문)의 데이터 형식이 무엇인지를 알려주는 역할을 한다.
즉 클라이언트와 서버는 이 ‘Content-Type’이 명시된 데이터 형식에 맞는 데이터들을 주고 받는 것이다.
2. 개발자들이 직접 실무에서 사용하는 대표적인 HTTP 헤더 예시
클라이언트와 서버 관점에서의 HTTP 헤더들은 개발자가 건드릴 일이 많이 없지만 개발자가 직접 코드 레벨에서 HTTP 헤더를 컨트롤 해야될 경우가 있다.
그 대표적인 두가지 예를 확인해보자
- Authorization
‘Authorization’ 헤더 정보는 클라이언트가 적절한 자격 증명을 가지고 있는지를 확인하기 위한 정보이다.
일반적으로 REST API 기반 애플리케이션의 경우 클라이언트와 서버 간의 로그인(사용자 ID/비밀번호) 인증에 통과한 클라이언트들은 ‘Authorization’ 헤더 정보를 기준으로 인증에 통과한 클라이언트가 맞는지 확인하는 절차를 거친다.
- User-Agent
실무에서 애플리케이션을 구현하다보면 여러가지 유형의 클라이언트가 하나의 서버 애플리케이션에 요청을 전송하는 경우가 굉장히 많다.
어떤 사용자는 데스크탑 또는 노트북 컴퓨터에 있는 웹 브라우저를 사용해서 서버에 요청을 보내고, 또 어떤 사용자는 스마트 폰이나 태블릿 등 모바일에서 요청을 보내는데 이 경우, 데스크탑에서 들어오는 요청과 모바일에서 들어오는 요청을 구분해서 응답 데이터를 다르게 보내줘야 되는 경우가 있을 수 있다.
예를 들면, 모바일 화면과 데스크탑 또는 노트북의 화면 크기의 차이가 많이 나기 때문에 더 큰 화면에서 더 많은 정보를 보여주기 위해 각각 데이터의 종류와 크기가 다를 수 있다.
이 경우, ‘User-Agent’ 정보를 이용해서 모바일 에이전트에서 들어오는 요청인지 모바일 이외에 다른 에이전트에서 들어오는 요청인지를 구분해서 처리할 수 있다.
정리하자면
HTTP 헤더(Header)는 HTTP 메시지(Messages)의 구성 요소 중 하나로써 클라이언트의 요청이나 서버의 응답에 포함되어 부가적인 정보를 HTTP 메시지에 포함할 수 있다.
HTTP Request 헤더(Header) 정보 얻기
- @RequestHeader 애너테이션을 이용해서 개별 헤더 정보 및 전체 헤더 정보를 얻을 수 있다.
- HttpServletRequest 또는 HttpEntity 객체로 헤더 정보를 얻을 수 있다.
HTTP Response 헤더(Header) 정보 추가
- ResponseEntity와 HttpHeaders를 이용해 헤더 정보를 추가할 수 있다.
- HttpServletResponse 객체를 이용해 헤더 정보를 추가할 수 있다.
Rest Client
클라이언트(Client)와 서버(Server)의 관계
웹 브라우저는 프론트엔드로 요청을 보내고 프론트 엔드를 그 요청을 받아 html 코드로 반환해준다.
하지만 프론트엔드는 다시 백엔드로 정보를 요청해 받아오는 클라이언트가 될 수 있고, 백엔드 또한 다른 백엔드로부터 정보를 받아올 수 있기에 클라이언트가 될 수 있다.
Rest Client란?
Rest Client란 말 그대로 Rest API 서버에 HTTP 요청을 보낼 수 있는 클라이언트 툴 또는 라이브러리를 의미한다. (Ex. Postman)
만약 UI가 없는 Backend A의 애플리케이션 내부에서 Backend B의 애플리케이션에 HTTP 요청을 보낼 때에는 UI가 없는 Rest Client 라이브러리를 사용하면 된다.
RestTemplate
Java에서 사용할 수 있는 HTTP Client 라이브러리로는 java.net.HttpURLConnection, Apache HttpComponents, OkHttp 3, Netty 등이 있다.
Spring에서는 이 HTTP Client 라이브러리 중 하나를 이용해서 원격지에 있는 다른 Backend 서버에 HTTP 요청을 보낼 수 있는 RestTemplate이라는 Rest Client API를 제공한다.
RestTemplate을 이용하면 Rest 엔드 포인트 지정, 헤더 설정, 파라미터 및 body 설정을 한 줄의 코드로 손쉽게 전송할 수 있다.
Template의 의미?
파워포인트 템플릿을 사용하면 PPT 디자인에 대한 고민없이 우리가 작성하고자 하는 내용만 채워넣으면 된다.
템플릿이란 개념을 위와같이 생각하자
RestTemplate 객체 생성
RestTemplate restTemplate =
new RestTemplate(new HttpComponentsClientHttpRequestFactory());
}
URI 생성
RestTemplate 객체를 생성했다면 HTTP Request를 전송할 Rest 엔드포인트의 URI를 지정해 주어야 한다.
UriComponents uriComponents =
UriComponentsBuilder
.newInstance()
.scheme("http")
.host("worldtimeapi.org")
// .port(80)
.path("/api/timezone/{continents}/{city}")
.encode()
.build();
URI uri = uriComponents.expand("Asia", "Seoul").toUri();
newInstance()
- UriComponentsBuilder 객체를 생성한다.
scheme()
- URI의 scheme을 설정한다.
host()
- 호스트 정보를 입력한다.
port()
- 디폴트 값은 80이므로 80 포트를 사용하는 호스트라면 생략 가능하다.
path()
- URI의 경로(path)를 입력한다.
- 위 코드에서는 URI의 path에서 {continents}, {city} 의 두 개의 템플릿 변수를 사용하고 있다.
- 두 개의 템플릿 변수는 uriComponents.expand("Asia", "Seoul").toUri(); 에서 expand() 메서드 파라미터의 문자열로 채워진다.
- 즉, 빌드 타임에 {continents}는 ‘Asia’, {city}는 ‘Seoul’로 변환된다.
encode()
- URI에 사용된 템플릿 변수들을 인코딩 해준다.
- 여기서 인코딩의 의미는 non-ASCII 문자와 URI에 적절하지 않은 문자를 Percent Encoding 한다는 의미이다.
build()
- UriComponents 객체를 생성한다.
expand()
- 파라미터로 입력한 값을 URI 템플릿 변수의 값으로 대체한다.
toUri()
- URI 객체를 생성한다.
요청 전송
String result = restTemplate.getForObject(uri, String.class);
getForObject(URI uri, Class<T> responseType)
- 기능 설명
- getForObject() 메서드는 HTTP Get 요청을 통해 서버의 리소스를 조회한다.
- 파라미터 설명
- URI uri
- Request를 전송할 엔드포인트의 URI 객체를 지정해준다.
- Class responseType
- 응답으로 전달 받을 클래스의 타입을 지정해준다.
- URI uri
getForObject()를 이용해 커스텀 클래스 타입으로 원하는 정보만 응답 받을 수도 있다.
Ex) WorldTime worldTime = restTemplate.getForObject(uri, WorldTime.class);
getForEntity()를 사용한 Response Body(바디, 컨텐츠) + Header(헤더) 정보 전달 받기
getForEntity() 메서드를 사용해서 헤더 정보와 바디 정보를 모두 전달 받을 수 있다.
ResponseEntity<WorldTime> response =
restTemplate.getForEntity(uri, WorldTime.class);
System.out.println(response.getHeaders().entrySet());
exchange() 를 사용한 응답 데이터 받기
exchange()를 사용하면 HTTP Method나 HTTP Request, HTTP Response 방식을 개발자가 직접 지정해서 유연하게 사용할 수 있다.
Ex)
ResponseEntity<WorldTime> response =
restTemplate.exchange(uri,
HttpMethod.GET,
null,
WorldTime.class);
- exchange(URI uri, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType)
- 기능 설명
- getForObject(), getForEntity() 등과 달리 exchange() 메서드는 HTTP Method, RequestEntity, ResponseEntity를 직접 지정해서 HTTP Request를 전송할 수 있는 가장 일반적인 방식이다.
- 파라미터 설명
- URI url
- Request를 전송할 엔드포인트의 URI 객체를 지정해준다.
- HttpMethod method
- HTTP Method 타입을 지정해준다.
- HttpEntity requestEntity
- HttpEntity 객체를 지정해준다.
- HttpEntity 객체를 통해 헤더 및 바디, 파라미터 등을 설정해줄 수 있다.
- Class responseType
- 응답으로 전달 받을 클래스의 타입을 지정해준다.
- URI url
- 기능 설명
총정리
- 웹 브라우저는 웹 서버로부터 HTML 컨텐츠를 제공받는 클라이언트 중 하나이다.
- 어떤 서버가 HTTP 통신을 통해서 다른 서버의 리소스를 이용한다면 그 때만큼은 클라이언트의 역할을 한다.
- Rest Client란 Rest API 서버에 HTTP 요청을 보낼 수 있는 클라이언트 툴 또는 라이브러리를 의미합니다.
- RestTemplate은 원격지에 있는 다른 Backend 서버에 HTTP 요청을 전송할 수 있는 Rest Client API 이다.
- RestTemplate 사용 단계
- RestTemplate 객체를 생성한다.
- HTTP 요청을 전송할 엔드포인트의 URI 객체를 생성한다.
- getForObject(), getForEntity(), exchange() 등을 이용해서 HTTP 요청을 전송한다.
- RestTemplate을 사용할 수 있는 기능 예
- 결제 서비스
- 카카오톡 등의 메시징 서비스
- Google Map 등의 지도 서비스
- 공공 데이터 포털, 카카오, 네이버 등에서 제공하는 Open API
- 기타 원격지 API 서버와의 통신
Open API 서비스 제공 사이트
* 공공 데이터 포털: https://www.data.go.kr/dataset/3043385/openapi.do
* 카카오 REST API: https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api
* 네이버 API: https://developers.naver.com/products/intro/plan/plan.md
* 구글 API 서비스: https://console.cloud.google.com
* 공공 인공지능 API 서비스: https://aiopen.etri.re.kr/
'코드스테이츠' 카테고리의 다른 글
코드스테이츠 43일차 (2) | 2022.06.27 |
---|---|
코드스테이츠 42일차 (0) | 2022.06.24 |
코드스테이츠 40일차 / Section 2 회고 (2) | 2022.06.22 |
코드스테이츠 39일차 (0) | 2022.06.21 |
코드스테이츠 38일차 (0) | 2022.06.20 |