[Vite+React]GET,POST,PATCH,PUT(MacOS)

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

Leave a Reply