JPA
스프링 부트 요청과 응답 동작 방식(GET/POST 방식)
yoooon1212
2024. 9. 27. 17:00
스프링부트 요청과 응답 흐름
- 클라이언트 측에서 /user로 GET 요청을 합니다. 이 요청은 톰캣을 거쳐 스프링 부트 애플리케이션으로 전달됩니다.
- 이때, 스프링 부트의 디스패처 서블릿(DispatcherServlet)이 요청을 받습니다. 디스패처 서블릿은 요청된 URL을 분석하고, 이를 처리할 수 있는 컨트롤러와 해당 메서드를 찾습니다.
- 컨트롤러에서 비즈니스 로직이 필요한 경우, 비즈니스 계층(Service) 및 퍼시스턴스 계층(Repository)을 통해 데이터를 처리합니다.
- 응답 과정에서 MIME 타입(예: JSON, HTML, XML 등)에 따라 다음과 같이 응답 방식이 달라집니다:
- JSON, XML 등 데이터 포맷으로 응답해야 하는 경우, 메시지 컨버터가 작동합니다. 예를 들어, @ResponseBody가 붙은 메서드는 메시지 컨버터를 사용하여 자바 객체를 JSON 또는 XML로 변환합니다.
- HTML 등의 뷰 템플릿이 필요한 경우, 뷰 리졸버(View Resolver)가 작동하여, 템플릿 엔진(예: Thymeleaf, JSP)을 통해 HTML 문서를 생성하여 클라이언트에게 반환합니다.
GET 방식과 URL 주소 설계
💡 멱등성(Idempotency)
같은 작업을 여러 번 수행해도 결과가 달라지지 않는 성질을 의미합니다.
이 개념은 특히 HTTP 메서드나 데이터베이스 연산에서 자주 사용됩니다.
- 멱등성을 가짐 (GET, PUT, DELET)
- 비 멱등성을 가짐 (POST)
안정성: 멱등성을 가진 연산은 중복 요청에 대해 안전합니다. 네트워크 문제로 인해 동일한 요청이 여러 번 전달되더라도, 최종 결과는 변하지 않으므로 안전하게 처리할 수 있습니다.
데이터 일관성: 멱등성은 시스템이 일관된 상태를 유지하도록 도와줍니다. 특히, 분산 시스템에서 동일한 작업이 여러 번 실행될 가능성이 있을 때, 멱등성은 데이터 무결성을 보장합니다.
요약
멱등성은 같은 작업을 여러 번 수행해도 결과가 달라지지 않는 성질을 의미하며, 주로 HTTP 메서드나 데이터베이스 연산에서 사용됩니다. 멱등성을 가진 연산은 안정적이고 예측 가능하며, 시스템의 일관성을 유지하는 데 중요한 역할을 합니다.
💡 쿼리 스트링(Query String)과 경로 매개변수(Path parameter)는 모두 HTTP 요청에서 파라미터를 전달하는 방식입니다. 그러나 다음과 같은 차이점이 있습니다.
쿼리 스트링(Query String)
URL 뒤에 '?'를 붙이고 파라미터를 key-value 쌍으로 전달합니다.
파라미터는 '&'로 구분되며, '='로 key와 value를 구분합니다.
브라우저의 캐시와 검색 엔진에서 높은 가중치를 부여합니다.
파라미터를 전달할 때 key와 value를 쌍으로 전달하기 때문에, 순서를 변경해도 문제가 없습니다.
예시 : http://example.com/search?q=keyword&page=1
경로 매개변수(Path parameter)
URL 경로의 일부로 파라미터를 전달합니다.
경로 변수(Path variable)를 사용하여 파라미터를 전달하며, { }로 변수를 감싸서 표시합니다.
일반적으로 RESTful API에서 사용되며, URL 자체가 파라미터 정보를 전달합니다.
파라미터를 전달할 때 key와 value를 쌍으로 전달하지 않습니다.
예시 : http://example.com/users/{id}
POST 방식
💡 JSON 데이터 타입 확인
문자열 ("name": "John")
숫자 ("age": 30)
불리언 ("isStudent": false)
객체 ("address": { "city": "New York", "zipCode": "10001" })
배열 ("hobbies": ["reading", "traveling", "swimming"])
null ("middleName": null)
{
"name": "John",
"age": 30,
"isStudent": false,
"address": {
"city": "New York",
"zipCode": "10001"
},
"hobbies": ["reading", "traveling", "swimming"],
"middleName": null
}
PostApiController
package com.tenco.demo_v1.controller;
import java.util.Map;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.tenco.demo_v1.dto.UserDTO;
@RestController // IoC 대상
@RequestMapping("/post")
public class PostApiController {
// 주소 설계
// http://localhost:8080/post/demo1 METHOD - Post
// 테스트 데이터 - { "name" : "둘리", "age": 11 }
// 이거는 header라서 test 시 테스트 데이터를 body에 json 형식으로 입력해줘야 함.
@PostMapping("/demo1")
// 사용자가 던진 데이터를 바이딩 처리 -> HTTP 메세지 바디 영역
public String demo1(@RequestBody Map<String, Object> reqData) {
// POST --> 리소스 취득, 생성 --> DB 접근기술 --> 영구히 데이터를 저장 한다.
StringBuffer sb = new StringBuffer();
reqData.entrySet().forEach( (entry) -> {
sb.append(entry.getKey() + " = " + entry.getValue());
});
// 메세지 컨버터가 동작 (리턴 타입 String )
return sb.toString();
}
@PostMapping("/demo2")
public String demo2(@RequestBody UserDTO userDTO) {
// POST -> 리소스 취득, 생성 -> DB 접근 기술 -> 영구히 데이터를 저장한다.
String userName = userDTO.getName();
System.out.println("userName: " + userName);
String userAge = userDTO.getAge();
String userPhoneNumber = userDTO.getPhoneNumber();
return "User Name : " + userName + ", User Age : " + userAge + ", User PhoneNumber : " + userPhoneNumber;
}
}
UserDTO
package com.tenco.demo_v1.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UserDTO {
private String name;
private String age;
private String phoneNumber;
}
요청값
{"name" : "둘리", "age": 11, "phone_number" : "010-1111-1111"}
Talend API나 postman을 사용하여 test 하기