ReactExample7
๐๐ป ์๋๋ Express์๋ฒ์์ GET,POST,PATCH,PUT์ ๋ํ ์ค๋ช
์
๋๋ค.
Below is an explanation of GET, POST, PATCH, and PUT on the Express server.
| ๋ฉ์๋/Method | ์ฉ๋/Use | ํน์ง/Characteristic |
| GET | ์กฐํ/Check | ๋ฆฌ์์ค ๊ฐ์ ธ์ค๊ธฐ ์ฃผ์์ฐฝ์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ – /users/1?name=kim |
| POST | ์์ฑ/Creation | ์ ๋ฆฌ์์ค ์ถ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋์ ์จ๊ฒจ์ ๋ณด๋ – { “name”: “John”, “age”: 30 } |
| PATCH | ๋ถ๋ถ์์ /Partial modification | ์ผ๋ถ ์์ฑ๋ง ๋ณ๊ฒฝ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋์ ์จ๊ฒจ์ ๋ณด๋ |
| PUT | ์ ์ฒด์์ /Edit all | ๊ธฐ์กด ๋ฆฌ์์ค๋ฅผ ์ ๋ฐ์ดํฐ๋ก ์์ ํ ๊ต์ฒด ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋์ ์จ๊ฒจ์ ๋ณด๋ |
๐๐ป์๋ฅผ ๋ค์ด, PATCH ์์ฒญ์์๋ { "nickname": "johnny" } ๊ฐ์ ์ผ๋ถ ํ๋๋ง ๋ณด๋ด๋ ๋์ง๋ง, PUT ์์ฒญ์์๋ ํด๋น ์ ์ ์ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ { "name": "V", "age": 30, "nickname": "johnny" }์ฒ๋ผ ๋ชจ๋ ๋ณด๋ด์ผ ํฉ๋๋ค.
๐๐ป ํ๋ก์ ํธ ์์ฑ / Create project
โ๏ธ Express Sever
% cd Example7/server/
% npm init -y
$ npm install express
โ๏ธ React
% npm create vite@latest client --template react-ts
๐๐ปNodejs Express Server
โ๏ธ Sever.js
const express = require("express");
const app = express();
const PORT = 3000;
app.use(express.json());
// ๊ฐ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค / Virtual Database
let users = [{ id: "1", name: "V", age: 20, nickname: "Cyberpunk2077" }];
// GET: ํน์ ์ ์ ์กฐํ / Specific user inquiry
app.get("/users/:id", (req, res) => {
const user = users.find((u) => u.id === req.params.id);
user
? res.json(user)
: res.status(404).json({ message: "์ ์ ์์/No user" });
});
// POST: ์๋ก์ด ์ ์ ์์ฑ / Create new user
app.post("/users", (req, res) => {
const newUser = { id: String(users.length + 1), ...req.body };
users.push(newUser);
res.status(201).json(newUser);
});
// PATCH: ๋ฐ์ดํฐ์ '์ผ๋ถ'๋ง ์์ (๊ธฐ์กด ๋ฐ์ดํฐ ์ ์ง)
// Modify only 'part' of the data (keep existing data)
app.patch("/users/:id", (req, res) => {
const index = users.findIndex((u) => u.id === req.params.id);
if (index !== -1) {
// ๊ธฐ์กด ๊ฐ + ๋ฐ๋ ๊ฐ ํฉ์น๊ธฐ / Merge existing value + changed value
users[index] = { ...users[index], ...req.body };
res.json(users[index]);
} else {
res.status(404).json({ message: "์ ์ ์์/No user" });
}
});
// PUT: ๋ฐ์ดํฐ '์ ์ฒด'๋ฅผ ๊ต์ฒด (๋ณด๋ด์ง ์์ ํ๋๋ ์ฌ๋ผ์ง)
// Replace 'all' data (unsent fields disappear)
app.put("/users/:id", (req, res) => {
const index = users.findIndex((u) => u.id === req.params.id);
if (index !== -1) {
// ๊ธฐ์กด ๋ด์ฉ ๋ฌด์ํ๊ณ ๋ฎ์ด์ฐ๊ธฐ / Ignore existing content and overwrite
users[index] = { id: req.params.id, ...req.body };
res.json(users[index]);
} else {
res.status(404).json({ message: "์ ์ ์์/No user" });
}
});
// DELETE: ๋ฐ์ดํฐ ์ญ์ / data deletion
app.delete("/users/:id", (req, res) => {
users = users.filter((u) => u.id !== req.params.id);
res.json({ message: `User ${req.params.id} ์ญ์ ์๋ฃ / Deletion complete` });
});
app.listen(PORT, () => console.log(`Server: http://localhost:${PORT}`));
๐๐ปReact Code
โ๏ธ ๋๋ ํ ๋ฆฌ์ด๋ / move directory
% cd Example7/client/src
โ๏ธ vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
server: {
proxy: {
// '/users'๋ก ์์ํ๋ ์์ฒญ์ ๋ฐฑ์๋ ์๋ฒ๋ก ๋ณด๋
๋๋ค.
// Send requests starting with '/users' to the backend server.
"/users": {
target: "http://localhost:3000",
changeOrigin: true,
},
},
},
});
โ๏ธApp.tsx
import React, { useState } from "react";
function UserComponent() {
const [userId, setUserId] = useState("1"); // ๊ธฐ๋ณธ๊ฐ 1๋ฒ ์ ์ / Default user number 1
const [userData, setUserData] = useState(null);
const [log, setLog] = useState("");
const updateUI = async (res) => {
const data = await res.json();
setUserData(res.ok ? data : null);
setLog(JSON.stringify(data, null, 2));
};
const getUser = () => fetch(`/users/${userId}`).then(updateUI);
const createUser = () =>
fetch("/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
name: "NewUser",
age: 30,
nickname: "SilverHand",
}),
}).then(updateUI);
const patchUser = () =>
fetch(`/users/${userId}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
// ๋๋ค์๋ง ๋ณ๊ฒฝ ์๋ / Try changing only your nickname
body: JSON.stringify({ nickname: "Johnny" }),
}).then(updateUI);
const putUser = () =>
fetch(`/users/${userId}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
// ์ ์ฒด ๊ต์ฒด (nickname ๋๋ฝ ์ ์ฌ๋ผ์ง ํ์ธ์ฉ)
// Replace all (to check if nickname disappears when missing)
body: JSON.stringify({ name: "John", age: 25 }),
}).then(updateUI);
const deleteUser = () =>
fetch(`/users/${userId}`, { method: "DELETE" }).then(async (res) => {
const data = await res.json();
setUserData(null);
setLog(data.message);
});
return (
<div style={{ padding: "20px", fontFamily: "sans-serif" }}>
<h1>HTTP Methods Playground</h1>
<input
value={userId}
onChange={(e) => setUserId(e.target.value)}
placeholder="User ID"
/>
<div style={{ margin: "10px 0", display: "flex", gap: "10px" }}>
<button onClick={getUser} style={{ background: "#e1e1e1" }}>
GET (์กฐํ/Search)
</button>
<button onClick={createUser} style={{ background: "#d1ffd1" }}>
POST (์์ฑ/Creation)
</button>
<button onClick={patchUser} style={{ background: "#fff4d1" }}>
PATCH (์ผ๋ถ์์ /Partial modification)
</button>
<button onClick={putUser} style={{ background: "#ffd1d1" }}>
PUT (์ ์ฒด๊ต์ฒด/Complete replacement)
</button>
<button onClick={deleteUser} style={{ background: "#eee" }}>
DELETE (์ญ์ /Deletion)
</button>
</div>
<div
style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "20px" }}
>
<section>
<h3>ํ์ฌ ๋ฐ์ดํฐ ์์ธ / State </h3>
{userData ? (
<div style={{ border: "1px solid blue", padding: "10px" }}>
<p>ID: {userData.id}</p>
<p>์ด๋ฆ/Name: {userData.name || "์์/none"}</p>
<p>๋์ด/Age: {userData.age || "์์/none"}</p>
<p>๋๋ค์/NickName: {userData.nickname || "์์/none"}</p>
</div>
) : (
<p>์กฐํ๋ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค./No data was retrieved.</p>
)}
</section>
<section>
<h3>์๋ฒ ์๋ณธ ์๋ต / Server Response(Raw JSON) </h3>
<pre style={{ background: "#f4f4f4", padding: "10px" }}>{log}</pre>
</section>
</div>
</div>
);
}
export default UserComponent;
๐๐ป ์คํฌ๋ฆฐ์ท/ScreenShot
