일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 공릉아파트부지
- V2X
- 아두이노 개발
- SpringBoot
- 50만호공급
- 아두이노
- Spring 웹개발
- 삼성의료원부지
- ObjectNode
- spring
- java programming
- 청년원가주택
- C-ITS
- 대방동군부지
- ESP32
- wave
- 아두이노라이브러리
- onnxruntime
- Ai
- DataBinding
- C-V2X
- 웹개발
- Spring 웹
- C#
- WPF
- ESP-DL
- http
- ListView
- 구체화하기
- 리츠주택
- Today
- Total
John's 개발자의 관심노트
HTTP Method 구현하기, "GET Method" with SpringBoot 본문
Spring 프레임워크를 기반으로 HTTP Method 를 구현하는 방법에 대해 알아보는 글 입니다.
HTTP 가 어떻게 사용되는지에 대해서 간략하게 알아보겠습니다.
위 그림처럼 각각의 Client 즉 일반 사용자들은 WEB Browser를 통해 여러 싸이트를 접속하고 정보를 얻어갑니다.
WEB Browser 의 보기좋은 웹페이지와, 수 많은 정보들은 Server 를 통해 가져옵니다.
우리가 WEB Browser 의 상단에 있는 주소창에 "www.naver.com" 이라고 입력하면
해당 주소의 서버로 웹페이지를 요청하게되고, 서버는 해당 웹페이지 데이터를 응답합니다.
이처럼 Internet 을 통해 Client 와 Server 간의 "Request 와 Response" 처리가 진행되는데
이 때 필요한 것이 HTTP Method 입니다.
물론 WEB Browser 에서 주소를 입력하면 HTTP Method 인 "GET" Method로 웹페이지를 요청하게됩니다.
지금부터 Server 와 Client 간 어떻게 요청이 이루어지고, 어떤식으로 데이터를 제공하는지를 알아보고
직접 구현해보는 지식을 쌓아보도록 하겠습니다.
"HTTP Method 구현하기" 시리즈에서는 "GET, POST, PUT" 을 구현하는 방법에 대해 다룰 예정입니다.
먼저 HTTP Method 의 종류는 무엇이 있는지 표로 정리해봤습니다.
위 표를 보면 멱등성? 이라는 단어가 보이는데요, 무슨 의미인지 잘 와닿지 않을거라 생각합니다.
멱등성이란 무엇인지에 대해 알아볼까요?
1. 멱등성이란?
멱등성의 사전적 의미는 어떤 대상에 수백,수천번의 연산을 적용해도 동일한 효과가 나오는 특징 또는 성질이라고합니다.
HTTP 에서 멱등성을 가져야하는 Method 는 "GET, PUT, DELETE" 입니다. (가장 많이 사용되는 Method 기준)
"GET" 은 멱등성의 의미랑 연관이 되는것 같은데 "PUT, DELETE" 는 왜 멱등성이 있다고 하는거지? 라는 생각이 드실거에요.
멱등성은 Client 요청의 대한 서버상태를 생각해야하는데 메소드별로 같은 요청을 여러번 보냈을 때를 생각해보면 이해가 쉽습니다.
같은 메소드를 여러번 요청을 해도 한번 요청한 결과와 같은지를 생각해보면 됩니다.
먼저 DELETE 가 왜 멱등성을 지니는지 설명을 해보자면,
DELETE 메소드는 리소스를 삭제하는 역할입니다. 처음 요청하면 해당 리소스가 삭제되고, 두번, 세번 반복으로 요청을해도
그 리소스는 삭제된 상태가 유지가 되기때문에 서버의 상태가 변하지 않습니다. 이는 DELETE에는 멱등성있다라고 해석이됩니다.
그렇다면 "PUT" 은 어떻게 멱등성이 있다고 설명이될까요?
PUT 의 기능은 리소스를 생성하거나, 대상 리소스를 나타내는 데이터를 오버라이트하는 역할입니다.
PUT을 요청하면 없던 자원은 생성이 되고, 이미 있었다면 정보만 변경이 됩니다. 그리고 두번, 세번 계속 요청을 한다고해서
해당 자원이 더 생기거나, 변경되는 일은 없으니 멱등성이 있다고 해석할 수 있지요.
그렇다면 "POST" 랑 대비가 되는데요,
POST 또한 자원을 생성하는 역할을 하는데 왜 PUT 과 다르게 멱등성이 없다고 할까요?
POST 는 그 기능 자체로 어떤 자원을 생성하는 기능을 합니다. 그렇기 때문에 같은 요청을 두번, 세번 반복적으로 계속 진행함에 따라
계속적으로 자원이 생성이 되며 이는 연산 횟수에 따라 자원이 계속 늘어나는 상황을 야기시키기 때문에 멱등성이 없다고 해석됩니다.
멱등성을 생각해보면서 HTTP Method 중 가장 많이 사용되는 몇가지를 살펴봤는데요,
이제는 각각을 구현해보도록 할까요?
제가 구현한 개발환경은 IntelliJ IDE 툴을 활용했는데요,
Spring Framework 기반으로 코드가 이렇게 구성이 되는구나 정도로 봐주시면 좋을 것 같습니다.
2. 테스트 구성
IntelliJ 로 WEB Server 를 구현하고, HTTP 테스트 툴로 동작을 검증해볼건데 구성은 이렇게 됩니다.
Talend API Tool 은 HTTP Client 역할로, WEB Server 를 테스트할 때 유용하게 사용하고 있어요.
아래 링크를 참고해서 다운로드 방법부터 설치까지 확인하실 수 있습니다.
[HTTP] HTTP Protocol Test 프로그램 설치 ("Talend API Tester")
Talend API Tester 라는 프로그램은, WEB Application 을 개발하거나, WEB Server 등을 개발할 때, REST API를 테스트하거나, HTTP Protocol 을 테스트 하기 위한 프로그램이다. 설치방법 "Chrome 웹 스토어" 접..
johnconomics.tistory.com
3. 실습 코드
일단 HTTP Method, 즉 서비스를 처리하는 Method가 모여있는 Class 를 "Controller" 라고 칭합니다.
이 Controller Class 를 생성할때,
Spring 에다가 이 클래스는 Controller 역할을 하는 클래스라고 알려주어야 하는데 그 때 사용하는 어노테이션입니다.
@RestController
다음은 해당 Controller 로 접근하기 위한 주소를 맵핑해주어야하는데 그 때 사용하는 어노테이션입니다.
@RequestMapping("/api")
위 두가지를 모두 사용해서 클래스를 생성하면 아래와 같이 작성됩니다.
@RestController
@RequestMapping("/api")
public class ApiController {
}
여기까지해서 우리는 "http://localhost:9090/api" 라는 URL 주소랑 맵핑이 되는 Class 를 생성했습니다.
다음으로 Get Method 를 구현해보도록 하겠습니다.
GET 요청이 있을 때 무슨 Method 를 호출할지 Mapping 작업을 해야하는데 그 때 사용하는 어노테이션 입니다.
@GetMapping("/hello")
@GetMapping("/hello/{name}")
두 종류로 제가 작성을 해뒀는데요, 뒤에 붙은 "{name}" 이 붙은 코드는 Path-Variable 을 활용하는 방식의 Mapping 입니다.
특정 URL 을 기준으로, "/hello/" 다음에 주소를 임의 값으로 변경해서 사용할 수 있도록 하는 방식이에요.
우리가 클라이언트로부터 파라미터를 전달받는 방법은 총 3가지가 있습니다.
"Path-Variable", "Query Variable", "Data Body" 가 있는데, Get Method 에서는 Body 영역을 사용하지 못하니깐,
"Path-Variable", "Query-Variable" 총 2가지만 전달받을 수 있겠네요.
아래 코드는 위 2가지 방식으로 클라이언트로부터 전달받은 파라미터 값을 활용하는 예제입니다.
첫 번째로 Path-Variable 을 활용한 예시,
// Get Method "PathVariable"
@GetMapping("/hello/{name}")
public ResponseEntity helloPathVariable(@PathVariable String name){
String ret = "Hello!, Your path-variable is \"" + name + "\"";
return ResponseEntity.status(HttpStatus.OK).body(ret);
}
// Get Method "PathVariable" modified
@GetMapping("/hello/{name}")
public ResponseEntity helloPathVariableModify(@PathVariable(value = "name") String userName){
String ret = "Hello!, Your path-variable is \"" + userName + "\"";
return ResponseEntity.status(HttpStatus.OK).body(ret);
}
첫 번째 방식은, "name" 이라는 변수명을 그대로 써야하는 경우고,
아래는 변수명을 임의로 변경해서 사용할 수 있는 방법입니다.
다음으로는 Query Variable 을 이용해서 구현해볼건데요, 그전에!
DTO 객체를 하나 만들고 들어가겠습니다.
Query Parameter 로 전달 받을 "User" 클래스 입니다.
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private int age;
}
다음으로는 Query-Variable 을 활용한 예시 입니다.
// Get Method "Query Variable"
@GetMapping("/hello/query")
public ResponseEntity helloQueryVariable(@RequestParam String name){
String ret = "Hello!, Your query-variable is \"" + name + "\"";
return ResponseEntity.status(HttpStatus.OK).body(ret);
}
// Get Method "Query Variable" used in MAP
@GetMapping("/hello/query/map")
public ResponseEntity helloDtoQueryVariable(@RequestParam Map<String, String> reqParam){
StringBuilder sb = new StringBuilder();
reqParam.forEach((key,value)->{
sb.append("{key:" + key + ",value:" + value + "}\n");
});
return ResponseEntity.status(HttpStatus.OK).body(sb.toString());
}
// Get Method "Query Variable" used in DTO
@GetMapping("/hello/query/user")
public ResponseEntity helloDtoQueryVariable(User user){
String ret = "Hello!, Your query-variable is \"" + user.getName() + ":" + user.getAge() + "\"";
return ResponseEntity.status(HttpStatus.OK).body(ret);
}
Query-Variable 을 전달받는 방법은 총 3가지로 나누어서 볼 수 있어요,
1. Query 의 Key 값과 동일한 변수명으로 직접 값을 입력받는 방법,
2. key 값이 무엇인지 상관없이, (Key, Value) 형태의 Map 형식으로 받는 방법,
3. 특정 DTO 클래스를 활용해서 데이터 객체 단위로 받는 방법 입니다.
위 2가지와 다르게 클래스 객체 단위로 입력받는 경우에는 "@RequestParam" 을 써줄 필요가 없습니다.
왜냐하면! 스프링에서 알아서 매칭을 다 해주고 있기때문에 해당 어노테이션은 의미가 없습니다.
하지만, 주의해야 할 부분이 있는데요, Query 값을 사용 시,
Client 로 부터 Key 값과 Value 값이 쌍을 이루는 형태로 값을 전달받는데
이때 Spring 에서 해당 Key 값을 우리가 작성한 Method 와 매칭하는 작업을 해주는데 당연히 그 이름이 같아야 매칭이 잘 되겠죠?
위 코드를 모두 종합해서 "ApiController" 라는 이름의 Controller 클래스를 구현한 코드입니다.
package com.example.testappserver.controller;
import com.example.testappserver.dto.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.coyote.Response;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/api")
public class ApiController {
// Get Method "Default"
@GetMapping("/hello")
public ResponseEntity hello(){
String ret = "Hello Spring WEB";
return ResponseEntity.status(HttpStatus.OK).body(ret);
}
// Get Method "PathVariable"
@GetMapping("/hello/{name}")
public ResponseEntity helloPathVariable(@PathVariable String name){
String ret = "Hello!, Your path-variable is \"" + name + "\"";
return ResponseEntity.status(HttpStatus.OK).body(ret);
}
// Get Method "PathVariable" modified
@GetMapping("/hello/path-variable/{name}")
public ResponseEntity helloPathVariableModify(@PathVariable(value = "name") String userName){
String ret = "Hello!, Your path-variable is \"" + userName + "\"";
return ResponseEntity.status(HttpStatus.OK).body(ret);
}
// Get Method "Query Variable"
@GetMapping("/hello/query")
public ResponseEntity helloQueryVariable(@RequestParam String name){
String ret = "Hello!, Your query-variable is \"" + name + "\"";
return ResponseEntity.status(HttpStatus.OK).body(ret);
}
// Get Method "Query Variable" used in MAP
@GetMapping("/hello/query/map")
public ResponseEntity helloDtoQueryVariable(@RequestParam Map<String, String> reqParam){
StringBuilder sb = new StringBuilder();
reqParam.forEach((key,value)->{
sb.append("{key:" + key + ",value:" + value + "}\n");
});
return ResponseEntity.status(HttpStatus.OK).body(sb.toString());
}
// Get Method "Query Variable" used in DTO
@GetMapping("/hello/query/user")
public ResponseEntity helloDtoQueryVariable(User user){
String ret = "Hello!, Your query-variable is \"" + user.getName() + ":" + user.getAge() + "\"";
return ResponseEntity.status(HttpStatus.OK).body(ret);
}
}
위 코드가 실행되었을 때의 예상 결과를 보면 아래와 같습니다.
오늘 위 코드를 구현하면서 사용한 어노테이션들에 대해서 정리를 해봤습니다.
📌 GET 구현 시, 사용한 어노테이션(Annotation) 정리!
1. "@RestController" → 아래 선언된 클래스를 Rest API Controller 로 사용하겠다라는 의미
2. "@RequestMapping("/test/api/get")" → Rest API Controller 접근을 위한 URI 에 대한 설정
3. "@GetMapping("resource")" → Class 내의 Method 와 URI Mapping
4. "@PathVariable String name" → Path-Variable 요청 시, 전달되는 인자값
5. "@RequestParam String name" → Query-Variable 요청 시, 전달되는 인자값
4. Talend API 실행화면
여기까지 해서 오늘은 HTTP Method 중에 "GET Method" 에 대해서 알아보았습니다.
다음 시간에는 "PUT" Method 를 구현해보는 시간을 가지도록 하겠습니다.
'[개발] > Spring WEB' 카테고리의 다른 글
Springboot REST API 구현하는 방법, Put Method 구현 (@PutMapping, @RestController) (1) | 2022.10.20 |
---|---|
Springboot REST API 구현하는 방법, POST Method 구현 (@PostMapping, @RestController) (0) | 2022.10.19 |
HTTP Protocol Test 프로그램 사용법 "Talend API Tester" (0) | 2022.10.14 |
JAVA Design Pattern, Strategy Pattern, 전략 패턴 (2) | 2022.10.14 |
JAVA Design Pattern, Facade Pattern 파사드 패턴 (0) | 2022.10.13 |