클라이언트(Frontend)와 서버(Backend) 간의 데이터 흐름
🚀 GET 요청의 전체 흐름: Front → Back → Front (React + Spring Boot + MySQL + Axios 사용)
📌 기본 개념
- Frontend (React + Axios) → 데이터를 요청
- Backend (Spring Boot + JPA) → 요청을 처리하고 DB에서 데이터 조회
- Database (MySQL) → 데이터를 저장하고 조회
🔄 전체 흐름 (GET 요청)
1️⃣ React (사용자가 데이터 요청)
⬇️ Axios GET 요청 전송 (HTTP 요청)
2️⃣ Spring Boot Controller (요청 수신)
⬇️ Service 계층으로 전달
3️⃣ Spring Boot Service (비즈니스 로직 실행)
⬇️ Repository에서 데이터 조회
4️⃣ Spring Boot Repository (DB에서 데이터 가져오기)
⬆️ 조회된 데이터를 Service로 반환
5️⃣ Service (Entity → DTO 변환 후 반환)
⬆️ Controller로 반환
6️⃣ Controller (프론트엔드로 JSON 응답 반환)
⬆️ HTTP 응답 (JSON 데이터)
7️⃣ React (Axios 응답 받아 UI 업데이트)
1️⃣ Frontend → Backend (GET 요청 보내기)
📌 React에서 사용자가 데이터를 요청하면 Axios를 통해 백엔드에 GET 요청을 보냄
📌 Axios를 사용한 API 호출 (React)
import { useEffect, useState } from "react";
import axios from "axios";
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
axios.get(`http://localhost:8080/users/${userId}`)
.then(response => setUser(response.data)) // JSON 데이터 저장
.catch(error => console.error("Error fetching user:", error));
}, [userId]);
if (!user) return <p>Loading...</p>;
return <h1>Welcome, {user.name}!</h1>;
}
export default UserProfile;
📌 요청 흐름
useEffect
에서 Axios를 사용해GET /users/{userId}
요청- 응답 데이터를
setUser
로 상태 업데이트 - UI에서 사용자 이름을 표시
2️⃣ Backend Controller (요청을 받아 처리)
📌 Spring Boot의 @GetMapping
을 사용해 요청을 처리
📌 Service에 데이터를 요청하고, 결과를 JSON으로 반환
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@GetMapping("/{userId}")
public ResponseEntity<UserDTO> getUser(@PathVariable Long userId) {
UserDTO user = userService.getUserById(userId);
return ResponseEntity.ok(user); // JSON 응답 반환
}
}
📌 흐름
- 프론트엔드에서
/users/{userId}
로GET
요청 @PathVariable
을 사용해 URL의{userId}
값을 가져옴userService.getUserById(userId)
호출
3️⃣ Backend Service (비즈니스 로직 처리)
📌 비즈니스 로직을 수행하고, DB에서 데이터를 조회한 후 DTO로 변환
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public UserDTO getUserById(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User not found"));
return new UserDTO(user); // Entity → DTO 변환 후 Controller로 반환
}
}
📌 흐름
Repository.findById(userId)
를 호출하여 DB에서 데이터 조회- 조회된
User(Entity)
를UserDTO
로 변환 UserDTO
를Controller
로 반환
4️⃣ Backend Repository (DB에서 데이터 가져오기)
📌 MySQL에서 데이터를 조회하는 역할
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
📌 흐름
JpaRepository
가SELECT * FROM users WHERE id = ?
실행- 조회된 데이터를
User(Entity)
객체로 변환하여 반환
5️⃣ Entity vs DTO 변환 (프론트엔드에 맞게 데이터 가공)
📌 Entity: DB와 1:1 매핑되는 객체
📌 DTO: 프론트엔드로 전달할 데이터만 포함하는 객체
// Entity (DB 테이블과 매핑됨)
@Entity
@Table(name = "users")
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
public User() {}
public User(String name, String email) {
this.name = name;
this.email = email;
}
// Getter & Setter
}
// DTO (클라이언트에 반환할 데이터만 포함)
public class UserDTO {
private String name;
private String email;
public UserDTO(User user) {
this.name = user.getName();
this.email = user.getEmail();
}
}
📌 흐름
Entity
는 DB의users
테이블과 1:1 매핑UserService
에서User(Entity)
→UserDTO
변환UserDTO
를JSON
으로 변환 후 프론트엔드로 전달
6️⃣ Backend → Frontend (JSON 응답 반환)
📌 Controller에서 DTO
를 JSON으로 변환 후 프론트엔드로 반환
return ResponseEntity.ok(user);
📌 응답 데이터 예시
{
"name": "John Doe",
"email": "john@example.com"
}
7️⃣ Frontend에서 응답을 받아 UI 업데이트
📌 React에서 데이터를 받아 화면을 업데이트
axios.get(`http://localhost:8080/users/1`)
.then(response => console.log(response.data)); // { name: "John Doe", email: "john@example.com" }
📌 React 컴포넌트에서 UI 업데이트
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
useEffect(() => {
axios.get(`http://localhost:8080/users/${userId}`)
.then(response => setUser(response.data))
.catch(error => console.error("Error fetching user:", error));
}, [userId]);
if (!user) return <p>Loading...</p>;
return <h1>Welcome, {user.name}!</h1>;
}
📌 흐름
- 백엔드에서
JSON
응답을 반환 - 프론트엔드에서 응답을 받아
useState
에 저장 - 데이터를 화면에 렌더링
📌 전체적인 흐름 (한눈에 보기)
[1] React (Axios로 GET 요청)
axios.get("/users/1")
[2] Spring Boot Controller가 요청 처리
@GetMapping("/{userId}")
[3] Service가 Repository 호출하여 DB 조회
userRepository.findById(userId)
[4] Repository가 MySQL에서 데이터 조회
SELECT * FROM users WHERE id = ?
[5] Service에서 Entity → DTO 변환
[6] Controller에서 JSON 응답 반환
return ResponseEntity.ok(userDTO);
[7] React에서 응답 받아 UI 업데이트
🚀 결론
1️⃣ React → Axios GET 요청 → Spring Boot Controller
2️⃣ Controller → Service → Repository → MySQL에서 데이터 조회
3️⃣ MySQL → Repository → Service → DTO 변환 후 Controller로 반환
4️⃣ Controller가 JSON 응답 반환 → React에서 UI 업데이트
🚀 POST 요청의 전체 흐름: Front → Back → Front (React + Spring Boot + MySQL + Axios 사용)
📌 기본 개념
- Frontend (React + Axios) → 사용자가 데이터를 입력하고 POST 요청
- Backend (Spring Boot + JPA) → 데이터를 처리하여 DB에 저장
- Database (MySQL) → 데이터를 저장 및 관리
🔄 전체 흐름 (POST 요청)
1️⃣ React (사용자가 폼 입력 후 저장 요청)
⬇️ Axios POST 요청 (JSON 데이터 포함)
2️⃣ Spring Boot Controller (요청 수신)
⬇️ Service 계층으로 데이터 전달
3️⃣ Spring Boot Service (비즈니스 로직 실행)
⬇️ Repository에서 데이터 저장
4️⃣ Spring Boot Repository (DB에 데이터 저장)
⬆️ 저장된 데이터를 Service로 반환
5️⃣ Service (Entity → DTO 변환 후 반환)
⬆️ Controller로 반환
6️⃣ Controller (프론트엔드로 JSON 응답 반환)
⬆️ HTTP 응답 (저장된 데이터 반환)
7️⃣ React (Axios 응답 받아 UI 업데이트)
1️⃣ Frontend → Backend (POST 요청 보내기)
📌 React에서 사용자가 데이터를 입력하고 버튼을 클릭하면 Axios를 통해 백엔드에 POST 요청을 보냄
📌 Axios를 사용한 API 호출 (React)
import { useState } from "react";
import axios from "axios";
function CreateUser() {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const handleSubmit = async (e) => {
e.preventDefault();
const userData = { name, email };
try {
const response = await axios.post("http://localhost:8080/users", userData);
console.log("User Created:", response.data); // 백엔드에서 반환된 데이터
} catch (error) {
console.error("Error creating user:", error);
}
};
return (
<form onSubmit={handleSubmit}>
<input type="text" placeholder="Name" onChange={(e) => setName(e.target.value)} />
<input type="email" placeholder="Email" onChange={(e) => setEmail(e.target.value)} />
<button type="submit">Create User</button>
</form>
);
}
export default CreateUser;
📌 요청 흐름
- 사용자가 이름과 이메일을 입력 후 버튼 클릭
handleSubmit()
이 실행되면서axios.post()
로 POST 요청 전송- 요청 본문(Body)에
{ name, email }
데이터를 포함
2️⃣ Backend Controller (요청을 받아 처리)
📌 Spring Boot의 @PostMapping
을 사용하여 요청을 처리
📌 프론트엔드에서 보낸 데이터를 받아 Service로 전달
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping
public ResponseEntity<UserDTO> createUser(@RequestBody UserDTO userDTO) {
UserDTO savedUser = userService.createUser(userDTO); // Service에 요청 전달
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser); // JSON 응답 반환
}
}
📌 흐름
@PostMapping
이 HTTPPOST
요청을 처리@RequestBody
를 사용해 JSON 데이터를userDTO
객체로 변환userService.createUser(userDTO)
를 호출하여 서비스 계층으로 전달
3️⃣ Backend Service (비즈니스 로직 처리)
📌 비즈니스 로직을 수행하고, 데이터 검증 후 Repository로 전달
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Transactional
public UserDTO createUser(UserDTO userDTO) {
User user = new User(userDTO.getName(), userDTO.getEmail()); // DTO → Entity 변환
User savedUser = userRepository.save(user); // DB에 저장
return new UserDTO(savedUser); // Entity → DTO 변환 후 Controller로 반환
}
}
📌 흐름
DTO
를Entity
로 변환 (UserDTO → User
)userRepository.save(user)
를 호출하여 DB에 저장- 저장된
User(Entity)
를UserDTO
로 변환 후 Controller에 반환
4️⃣ Backend Repository (DB에 데이터 저장)
📌 MySQL에서 데이터를 저장하는 역할
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
📌 흐름
JpaRepository
가INSERT INTO users (...) VALUES (...)
실행- 저장된 데이터를
User(Entity)
객체로 반환
5️⃣ Entity vs DTO 변환 (프론트엔드에 맞게 데이터 가공)
📌 Entity: DB와 1:1 매핑되는 객체
📌 DTO: 프론트엔드로 전달할 데이터만 포함하는 객체
// Entity (DB 테이블과 매핑됨)
@Entity
@Table(name = "users")
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
public User() {}
public User(String name, String email) {
this.name = name;
this.email = email;
}
// Getter & Setter
}
// DTO (클라이언트에 반환할 데이터만 포함)
public class UserDTO {
private String name;
private String email;
public UserDTO(User user) {
this.name = user.getName();
this.email = user.getEmail();
}
}
📌 흐름
Entity
는 DB의users
테이블과 1:1 매핑UserService
에서User(Entity)
→UserDTO
변환UserDTO
를JSON
으로 변환 후 프론트엔드로 전달
6️⃣ Backend → Frontend (JSON 응답 반환)
📌 Controller에서 저장된 데이터를 JSON으로 변환 후 반환
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
📌 응답 데이터 예시
{
"name": "John Doe",
"email": "john@example.com"
}
7️⃣ Frontend에서 응답을 받아 UI 업데이트
📌 React에서 데이터를 받아 화면을 업데이트
axios.post("http://localhost:8080/users", { name: "John Doe", email: "john@example.com" })
.then(response => console.log("Created User:", response.data));
📌 전체적인 흐름 (한눈에 보기)
[1] React (Axios로 POST 요청)
axios.post("/users", { name, email })
[2] Spring Boot Controller가 요청 처리
@PostMapping + @RequestBody
[3] Service가 Repository 호출하여 DB 저장
userRepository.save(user)
[4] Repository가 MySQL에 데이터 저장
INSERT INTO users (name, email) VALUES (?, ?)
[5] Service에서 Entity → DTO 변환
[6] Controller에서 JSON 응답 반환
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
[7] React에서 응답 받아 UI 업데이트
🚀 결론
1️⃣ React → Axios POST 요청 → Spring Boot Controller
2️⃣ Controller → Service → Repository → MySQL에 데이터 저장
3️⃣ MySQL → Repository → Service → DTO 변환 후 Controller로 반환
4️⃣ Controller가 JSON 응답 반환 → React에서 UI 업데이트
🚀 PUT 요청의 전체 흐름: Front → Back → Front (React + Spring Boot + MySQL + Axios 사용)
📌 기본 개념
- Frontend (React + Axios) → 사용자가 데이터를 수정하고 PUT 요청
- Backend (Spring Boot + JPA) → 데이터를 업데이트 후 DB 반영
- Database (MySQL) → 기존 데이터를 수정 및 저장
🔄 전체 흐름 (PUT 요청)
1️⃣ React (사용자가 수정 요청)
⬇️ Axios PUT 요청 (JSON 데이터 포함)
2️⃣ Spring Boot Controller (요청 수신)
⬇️ Service 계층으로 데이터 전달
3️⃣ Spring Boot Service (비즈니스 로직 실행)
⬇️ Repository에서 기존 데이터 조회 후 수정
4️⃣ Spring Boot Repository (DB에 데이터 업데이트)
⬆️ 수정된 데이터를 Service로 반환
5️⃣ Service (Entity → DTO 변환 후 반환)
⬆️ Controller로 반환
6️⃣ Controller (프론트엔드로 JSON 응답 반환)
⬆️ HTTP 응답 (수정된 데이터 반환)
7️⃣ React (Axios 응답 받아 UI 업데이트)
1️⃣ Frontend → Backend (PUT 요청 보내기)
📌 React에서 사용자가 데이터를 수정하고, Axios를 통해 백엔드에 PUT 요청을 보냄
📌 Axios를 사용한 API 호출 (React)
import { useState } from "react";
import axios from "axios";
function UpdateUser({ userId }) {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const handleUpdate = async (e) => {
e.preventDefault();
const userData = { name, email };
try {
const response = await axios.put(`http://localhost:8080/users/${userId}`, userData);
console.log("User Updated:", response.data); // 백엔드에서 반환된 데이터
} catch (error) {
console.error("Error updating user:", error);
}
};
return (
<form onSubmit={handleUpdate}>
<input type="text" placeholder="New Name" onChange={(e) => setName(e.target.value)} />
<input type="email" placeholder="New Email" onChange={(e) => setEmail(e.target.value)} />
<button type="submit">Update User</button>
</form>
);
}
export default UpdateUser;
📌 요청 흐름
- 사용자가 이름과 이메일을 입력 후 업데이트 버튼 클릭
handleUpdate()
실행 →axios.put()
로 PUT 요청 전송- 요청 본문(Body)에
{ name, email }
데이터를 포함
2️⃣ Backend Controller (요청을 받아 처리)
📌 Spring Boot의 @PutMapping
을 사용하여 요청을 처리
📌 Service에 데이터를 요청하고, 결과를 JSON으로 반환
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PutMapping("/{userId}")
public ResponseEntity<UserDTO> updateUser(
@PathVariable Long userId,
@RequestBody UserDTO userDTO) {
UserDTO updatedUser = userService.updateUser(userId, userDTO);
return ResponseEntity.ok(updatedUser); // JSON 응답 반환
}
}
📌 흐름
@PutMapping("/{userId}")
가 HTTPPUT
요청을 처리@RequestBody
를 사용해 JSON 데이터를userDTO
객체로 변환userService.updateUser(userId, userDTO)
를 호출하여 서비스 계층으로 전달
3️⃣ Backend Service (비즈니스 로직 처리)
📌 비즈니스 로직을 수행하고, 기존 데이터를 조회한 후 수정하여 저장
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Transactional
public UserDTO updateUser(Long userId, UserDTO userDTO) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User not found"));
user.setName(userDTO.getName()); // 기존 값 수정
user.setEmail(userDTO.getEmail());
User updatedUser = userRepository.save(user); // 변경된 데이터 저장
return new UserDTO(updatedUser); // Entity → DTO 변환 후 Controller로 반환
}
}
📌 흐름
Repository.findById(userId)
를 호출하여 기존 데이터 조회- 조회된
User(Entity)
의 이름과 이메일을 수정 userRepository.save(user)
를 호출하여 변경된 데이터 DB에 저장- 수정된
User(Entity)
를UserDTO
로 변환 후 Controller에 반환
4️⃣ Backend Repository (DB에 데이터 수정)
📌 JPA를 이용해 DB에서 데이터를 조회 후 업데이트
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
📌 흐름
JpaRepository
가SELECT * FROM users WHERE id = ?
실행하여 기존 데이터 조회- 엔티티의 데이터를 수정 후
UPDATE users SET name = ?, email = ? WHERE id = ?
실행 - 수정된 데이터를
User(Entity)
객체로 반환
5️⃣ Entity vs DTO 변환 (프론트엔드에 맞게 데이터 가공)
📌 Entity: DB와 1:1 매핑되는 객체
📌 DTO: 프론트엔드로 전달할 데이터만 포함하는 객체
// Entity (DB 테이블과 매핑됨)
@Entity
@Table(name = "users")
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
public User() {}
public User(String name, String email) {
this.name = name;
this.email = email;
}
// Getter & Setter
}
// DTO (클라이언트에 반환할 데이터만 포함)
public class UserDTO {
private String name;
private String email;
public UserDTO(User user) {
this.name = user.getName();
this.email = user.getEmail();
}
}
📌 흐름
Entity
는 DB의users
테이블과 1:1 매핑UserService
에서User(Entity)
→UserDTO
변환UserDTO
를JSON
으로 변환 후 프론트엔드로 전달
6️⃣ Backend → Frontend (JSON 응답 반환)
📌 Controller에서 수정된 데이터를 JSON으로 변환 후 반환
return ResponseEntity.ok(updatedUser);
📌 응답 데이터 예시
{
"name": "John Doe",
"email": "john@example.com"
}
7️⃣ Frontend에서 응답을 받아 UI 업데이트
📌 React에서 데이터를 받아 화면을 업데이트
axios.put(`http://localhost:8080/users/1`, { name: "John Doe", email: "john@example.com" })
.then(response => console.log("Updated User:", response.data));
📌 전체적인 흐름 (한눈에 보기)
[1] React (Axios로 PUT 요청)
axios.put("/users/1", { name, email })
[2] Spring Boot Controller가 요청 처리
@PutMapping("/{userId}") + @RequestBody
[3] Service가 Repository 호출하여 기존 데이터 조회 및 수정
userRepository.findById(userId)
user.setName(newName)
userRepository.save(user)
[4] Repository가 MySQL에서 데이터 수정
UPDATE users SET name = ?, email = ? WHERE id = ?
[5] Service에서 Entity → DTO 변환
[6] Controller에서 JSON 응답 반환
return ResponseEntity.ok(updatedUser);
[7] React에서 응답 받아 UI 업데이트
🚀 결론
1️⃣ React → Axios PUT 요청 → Spring Boot Controller
2️⃣ Controller → Service → Repository → MySQL에서 기존 데이터 조회 및 수정
3️⃣ MySQL → Repository → Service → DTO 변환 후 Controller로 반환
4️⃣ Controller가 JSON 응답 반환 → React에서 UI 업데이트
🚀 PATCH 요청의 전체 흐름: Front → Back → Front (React + Spring Boot + MySQL + Axios 사용)
📌 PATCH 요청의 특징
- PUT과 차이점:
PUT
은 전체 데이터를 수정 (모든 필드 필요)PATCH
는 일부 필드만 수정 가능 (변경된 필드만 보냄)
- 프론트엔드(React + Axios) → 사용자가 데이터를 수정하고 PATCH 요청 전송
- 백엔드(Spring Boot + JPA) → 변경된 데이터만 업데이트 후 DB 반영
- 데이터베이스(MySQL) → 기존 데이터에서 일부 필드만 수정 및 저장
🔄 전체 흐름 (PATCH 요청)
1️⃣ React (사용자가 특정 필드 수정 요청)
⬇️ Axios PATCH 요청 (변경된 JSON 데이터만 포함)
2️⃣ Spring Boot Controller (요청 수신)
⬇️ Service 계층으로 데이터 전달
3️⃣ Spring Boot Service (비즈니스 로직 실행)
⬇️ Repository에서 기존 데이터 조회 후 부분 수정
4️⃣ Spring Boot Repository (DB에 변경된 데이터만 업데이트)
⬆️ 수정된 데이터를 Service로 반환
5️⃣ Service (Entity → DTO 변환 후 반환)
⬆️ Controller로 반환
6️⃣ Controller (프론트엔드로 JSON 응답 반환)
⬆️ HTTP 응답 (수정된 데이터 반환)
7️⃣ React (Axios 응답 받아 UI 업데이트)
1️⃣ Frontend → Backend (PATCH 요청 보내기)
📌 React에서 사용자가 일부 데이터만 수정하고, Axios를 통해 백엔드에 PATCH 요청을 보냄
📌 Axios를 사용한 API 호출 (React)
import { useState } from "react";
import axios from "axios";
function UpdateUserEmail({ userId }) {
const [email, setEmail] = useState("");
const handleUpdate = async (e) => {
e.preventDefault();
const updatedData = { email }; // name은 변경하지 않음
try {
const response = await axios.patch(`http://localhost:8080/users/${userId}`, updatedData);
console.log("User Updated:", response.data); // 백엔드에서 반환된 데이터
} catch (error) {
console.error("Error updating user:", error);
}
};
return (
<form onSubmit={handleUpdate}>
<input type="email" placeholder="New Email" onChange={(e) => setEmail(e.target.value)} />
<button type="submit">Update Email</button>
</form>
);
}
export default UpdateUserEmail;
📌 요청 흐름
- 사용자가 이메일만 입력 후 업데이트 버튼 클릭
handleUpdate()
실행 →axios.patch()
로 PATCH 요청 전송- 요청 본문(Body)에
{ email }
변경된 필드만 포함
2️⃣ Backend Controller (요청을 받아 처리)
📌 Spring Boot의 @PatchMapping
을 사용하여 요청을 처리
📌 Service에 데이터를 요청하고, 결과를 JSON으로 반환
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PatchMapping("/{userId}")
public ResponseEntity<UserDTO> updateUserPartially(
@PathVariable Long userId,
@RequestBody Map<String, Object> updates) {
UserDTO updatedUser = userService.updateUserPartially(userId, updates);
return ResponseEntity.ok(updatedUser); // JSON 응답 반환
}
}
📌 흐름
@PatchMapping("/{userId}")
가 HTTPPATCH
요청을 처리@RequestBody
를Map<String, Object>
형태로 받아 변경된 필드만 처리userService.updateUserPartially(userId, updates)
를 호출하여 서비스 계층으로 전달
3️⃣ Backend Service (비즈니스 로직 처리)
📌 비즈니스 로직을 수행하고, 기존 데이터를 조회한 후 일부 필드만 수정하여 저장
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Transactional
public UserDTO updateUserPartially(Long userId, Map<String, Object> updates) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User not found"));
updates.forEach((key, value) -> {
switch (key) {
case "name": user.setName((String) value); break;
case "email": user.setEmail((String) value); break;
default: throw new IllegalArgumentException("Invalid field: " + key);
}
});
User updatedUser = userRepository.save(user); // 변경된 데이터 저장
return new UserDTO(updatedUser); // Entity → DTO 변환 후 Controller로 반환
}
}
📌 흐름
Repository.findById(userId)
를 호출하여 기존 데이터 조회updates.forEach()
를 사용하여 변경된 필드만 수정userRepository.save(user)
를 호출하여 변경된 데이터 DB에 저장- 수정된
User(Entity)
를UserDTO
로 변환 후 Controller에 반환
4️⃣ Backend Repository (DB에 데이터 수정)
📌 JPA를 이용해 DB에서 데이터를 조회 후 업데이트
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
📌 흐름
JpaRepository
가SELECT * FROM users WHERE id = ?
실행하여 기존 데이터 조회- 엔티티의 일부 데이터를 수정 후
UPDATE users SET 필드명 = ? WHERE id = ?
실행 - 수정된 데이터를
User(Entity)
객체로 반환
5️⃣ Entity vs DTO 변환 (프론트엔드에 맞게 데이터 가공)
// Entity (DB 테이블과 매핑됨)
@Entity
@Table(name = "users")
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
public User() {}
public User(String name, String email) {
this.name = name;
this.email = email;
}
// Getter & Setter
}
// DTO (클라이언트에 반환할 데이터만 포함)
public class UserDTO {
private String name;
private String email;
public UserDTO(User user) {
this.name = user.getName();
this.email = user.getEmail();
}
}
📌 흐름
Entity
는 DB의users
테이블과 1:1 매핑UserService
에서User(Entity)
→UserDTO
변환UserDTO
를JSON
으로 변환 후 프론트엔드로 전달
6️⃣ Backend → Frontend (JSON 응답 반환)
📌 Controller에서 수정된 데이터를 JSON으로 변환 후 반환
return ResponseEntity.ok(updatedUser);
📌 응답 데이터 예시
{
"name": "John Doe",
"email": "updated@example.com"
}
7️⃣ Frontend에서 응답을 받아 UI 업데이트
📌 React에서 데이터를 받아 화면을 업데이트
axios.patch(`http://localhost:8080/users/1`, { email: "updated@example.com" })
.then(response => console.log("Updated User:", response.data));
📌 전체적인 흐름 (한눈에 보기)
[1] React (Axios로 PATCH 요청)
axios.patch("/users/1", { email })
[2] Spring Boot Controller가 요청 처리
@PatchMapping("/{userId}") + @RequestBody Map<String, Object>
[3] Service가 Repository 호출하여 기존 데이터 조회 및 수정
userRepository.findById(userId)
updates.forEach()로 변경된 필드만 수정
userRepository.save(user)
[4] Repository가 MySQL에서 변경된 필드만 업데이트
UPDATE users SET email = ? WHERE id = ?
[5] Service에서 Entity → DTO 변환
[6] Controller에서 JSON 응답 반환
return ResponseEntity.ok(updatedUser);
[7] React에서 응답 받아 UI 업데이트
🚀 결론
1️⃣ React → Axios PATCH 요청 → Spring Boot Controller
2️⃣ Controller → Service → Repository → MySQL에서 기존 데이터 조회 및 일부 수정
3️⃣ Controller가 JSON 응답 반환 → React에서 UI 업데이트
🚀 DELETE 요청의 전체 흐름: Front → Back → Front (React + Spring Boot + MySQL + Axios 사용)
📌 DELETE 요청의 특징
- 데이터를 삭제하는 요청
- 프론트엔드(React + Axios) → 사용자가 삭제 버튼 클릭 시 DELETE 요청 전송
- 백엔드(Spring Boot + JPA) → 데이터를 삭제 후 DB 반영
- 데이터베이스(MySQL) → 해당 데이터 삭제 처리
🔄 전체 흐름 (DELETE 요청)
1️⃣ React (사용자가 삭제 요청)
⬇️ Axios DELETE 요청 (경로에 ID 포함)
2️⃣ Spring Boot Controller (요청 수신)
⬇️ Service 계층으로 데이터 전달
3️⃣ Spring Boot Service (비즈니스 로직 실행)
⬇️ Repository에서 데이터 삭제
4️⃣ Spring Boot Repository (DB에서 데이터 삭제)
⬆️ 삭제 완료 후 Service로 반환
5️⃣ Service (삭제 완료 후 반환)
⬆️ Controller로 반환
6️⃣ Controller (프론트엔드로 JSON 응답 반환)
⬆️ HTTP 응답 (삭제 성공 메시지 반환)
7️⃣ React (Axios 응답 받아 UI 업데이트)
1️⃣ Frontend → Backend (DELETE 요청 보내기)
📌 React에서 사용자가 삭제 버튼을 클릭하면 Axios를 통해 백엔드에 DELETE 요청을 보냄
📌 Axios를 사용한 API 호출 (React)
import axios from "axios";
function DeleteUser({ userId, onDelete }) {
const handleDelete = async () => {
try {
await axios.delete(`http://localhost:8080/users/${userId}`);
console.log("User Deleted");
onDelete(userId); // UI에서 삭제 처리
} catch (error) {
console.error("Error deleting user:", error);
}
};
return <button onClick={handleDelete}>Delete User</button>;
}
export default DeleteUser;
📌 요청 흐름
- 사용자가 삭제 버튼 클릭
handleDelete()
실행 →axios.delete()
로 DELETE 요청 전송- 서버에서 사용자 ID에 해당하는 데이터 삭제
2️⃣ Backend Controller (요청을 받아 처리)
📌 Spring Boot의 @DeleteMapping
을 사용하여 요청을 처리
📌 Service에 삭제 요청을 전달하고, 결과를 JSON으로 반환
@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@DeleteMapping("/{userId}")
public ResponseEntity<String> deleteUser(@PathVariable Long userId) {
userService.deleteUser(userId);
return ResponseEntity.ok("User deleted successfully");
}
}
📌 흐름
@DeleteMapping("/{userId}")
가 HTTPDELETE
요청을 처리@PathVariable
을 사용해 URL의{userId}
값을 가져옴userService.deleteUser(userId)
를 호출하여 서비스 계층으로 전달- 삭제 성공 후
"User deleted successfully"
메시지를 반환
3️⃣ Backend Service (비즈니스 로직 처리)
📌 비즈니스 로직을 수행하고, 삭제할 데이터를 조회한 후 삭제
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Transactional
public void deleteUser(Long userId) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User not found"));
userRepository.delete(user); // 데이터 삭제
}
}
📌 흐름
Repository.findById(userId)
를 호출하여 삭제할 데이터 조회- 데이터가 존재하면
userRepository.delete(user)
를 호출하여 삭제 - 삭제 후 Controller에 성공 응답 반환
4️⃣ Backend Repository (DB에서 데이터 삭제)
📌 JPA를 이용해 DB에서 데이터를 삭제
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}
📌 흐름
JpaRepository
가DELETE FROM users WHERE id = ?
실행- 삭제 성공 후 Service에 반환
5️⃣ Backend → Frontend (JSON 응답 반환)
📌 Controller에서 삭제 성공 메시지를 JSON으로 변환 후 반환
return ResponseEntity.ok("User deleted successfully");
📌 응답 데이터 예시
"User deleted successfully"
6️⃣ Frontend에서 응답을 받아 UI 업데이트
📌 React에서 데이터를 받아 화면을 업데이트
axios.delete(`http://localhost:8080/users/1`)
.then(() => console.log("User Deleted"));
📌 React 컴포넌트에서 UI 업데이트
function UserList() {
const [users, setUsers] = useState([
{ id: 1, name: "John Doe" },
{ id: 2, name: "Jane Doe" }
]);
const handleDelete = (userId) => {
setUsers(users.filter(user => user.id !== userId)); // 삭제된 데이터 UI에서 제거
};
return (
<div>
{users.map(user => (
<div key={user.id}>
<span>{user.name}</span>
<DeleteUser userId={user.id} onDelete={handleDelete} />
</div>
))}
</div>
);
}
📌 흐름
- 사용자 목록에서 삭제 버튼 클릭
axios.delete()
요청 후 서버에서 삭제 처리- 응답을 받은 후
setUsers()
를 사용해 삭제된 데이터 UI에서 제거
📌 전체적인 흐름 (한눈에 보기)
[1] React (Axios로 DELETE 요청)
axios.delete("/users/1")
[2] Spring Boot Controller가 요청 처리
@DeleteMapping("/{userId}")
[3] Service가 Repository 호출하여 기존 데이터 조회 및 삭제
userRepository.findById(userId)
userRepository.delete(user)
[4] Repository가 MySQL에서 데이터 삭제
DELETE FROM users WHERE id = ?
[5] Service에서 삭제 완료 후 Controller로 반환
[6] Controller에서 JSON 응답 반환
return ResponseEntity.ok("User deleted successfully");
[7] React에서 응답 받아 UI 업데이트
setUsers(users.filter(user => user.id !== userId));
🚀 결론
1️⃣ React → Axios DELETE 요청 → Spring Boot Controller
2️⃣ Controller → Service → Repository → MySQL에서 데이터 삭제
3️⃣ 삭제 성공 후 Controller가 JSON 응답 반환 → React에서 UI 업데이트
'웹 개발' 카테고리의 다른 글
웹 개발 - 데이터 흐름, 네이밍 (0) | 2025.03.02 |
---|---|
GitHub 사용법 (0) | 2025.03.02 |
URL 경로에 포함된 동적인 값을 처리하는 방법(Spring Boot). (0) | 2025.02.26 |
JPA 연관관계 매핑 정리 (0) | 2025.02.25 |
React - Router의 동작 흐름 (0) | 2025.02.24 |