[TIL/React] 2024/07/17
✅ 1. 시작이 왜 안 됨?전투적인 정보처리기사 공부를 잠시 멈추고 다시 개발 공부에 돌입하려 했는데, 왜 때문인지 npm run serve(or dev)가 돌아가질 않았다.Connection이 안 된다는 것은, mongoose 쪽 코드를 봐야 한다는 뜻.ㅋㅋ 진짜 잘
✅ 1. 시작이 왜 안 됨?
전투적인 정보처리기사 공부를 잠시 멈추고 다시 개발 공부에 돌입하려 했는데, 왜 때문인지 npm run serve(or dev)가 돌아가질 않았다.

Connection이 안 된다는 것은, mongoose 쪽 코드를 봐야 한다는 뜻.

ㅋㅋ 진짜 잘못한 거 없음.~~(은 아니었다)~~
문제는 반드시 위 코드에서 발생한 것이 맞는데, 코드 상의 문제가 아니라면 소거법에 의해 MongoDB 설정만이 남게 된다.

IP Address 설정은 개나 줘버렸던 것.

1시간이 소요된 작업이지만, IP Address 설정의 중요성을 깨우쳤으니 완전 럭키비키니시티임!

✅ 2. Read API with 'id'
우선 인도 형님이 시키는 대로 크롬 extension을 하나 다운로드했다.



잘 했는데 왜 또 안 되는 것이냐.

ㅋㅋ ``/////////////`` 아 개발 너무 좋아.(정신 안 차림요?)
요청 시에 붙인 id를, req.params를 통해 받아서 변수에 담고, 결국 findById 메서드를 통해 특정 항목의 데이터를 가져올 수 있게 된다.

✅ 3. Update API

id를 통해 특정 데이터만을 읽은 것과 같이, 업데이트도 특정 데이터에 대해서 이루어질 것이기에, id를 활용해 주어야 한다. findByIdAndUpdate 함수에 id와 req.body를 전달한다. 업데이트할 대상의 id를 찾은 뒤, 업데이트의 내용을 전달하는 것이다.
일치하는 product data가 없다면 404를 return 할 것이고, 존재한다면(=업데이트되었다면) 해당 id에 일치하는 데이터를 찾아서 200 상태 코드와 함께 반환하게 된다. 한마디로 업데이트에 성공했다는 뜻이다. insomnia로 해당 코드를 테스트했다.

PUT 요청을 통해 name이 적절히 업데이트되었음을 확인할 수 있다.
✅ 4. Delete API

Delete 로직 역시 특정 데이터에 대해서 이루어진다. 따라서 id를 전달하고 findByIdAndDelete 메서드를 통해 id와 일치하는 데이터를 삭제한다.
삭제가 완료되면 상태 코드 200과 함께 "Product deleted successfully."라는 메시지를 확인할 수 있다.

DELETE 요청을 한 직후의 모습이다.

다시 모든 데이터를 받아오면, pizza 데이터가 삭제되었음을 확인할 수 있다.
✅ 5. Form URL Encoded
Form URL Encoded 방식으로 데이터를 추가할 수 있다.

거짓말이다. 그냥은 못한다. middleware를 추가해야 한다.


middleware를 추가하고 타입 이슈를 잘 고려하면, 정상적으로 동작하게 됨을 확인할 수 있다.
✅ 6. Routes & Controllers
그런데 이제 인도 형님이 우려하는 것은, 이런 식으로 계속 진행하다 보면 index.js 파일이 굉장히 뚱뚱해진다는 것이다. 인도 형님이 "이 부분부터가 나으 영상의 하이라이트임!"이라고 하셨다.
index.js ✍️
// index.js
const express = require("express");
const mongoose = require("mongoose");
const productRoute = require("./routes/product.route");
const app = express();
require("dotenv").config();
// middleware
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// router
app.use("/api/products", productRoute);
const PORT = process.env.PORT || 3000;
app.get("/", (req, res) => {
res.send("Hello from Node API Server Updated");
});
mongoose
.connect(process.env.MONGODB_URL)
.then(() => {
console.log("Connected to database!");
app.listen(PORT, () => {
console.log("Server is running on port 3000");
});
})
.catch(() => {
console.log("Connection failed!");
});
routes/product.route.js ✍️
// routes/product.route.js
const express = require("express");
const router = express.Router();
const {
getProducts,
getProduct,
createProduct,
updateProduct,
deleteProduct,
} = require("../controllers/product.controller");
router.get("/", getProducts);
router.get("/:id", getProduct);
router.post("/", createProduct);
router.put("/:id", updateProduct);
router.delete("/:id", deleteProduct);
module.exports = router;
controllers/product.controller.js ✍️
// controllers/product.controller.js
const Product = require("../models/product.model");
// get all products
const getProducts = async (req, res) => {
try {
const product = await Product.find({});
res.status(200).json(product);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// get one product
const getProduct = async (req, res) => {
try {
const { id } = req.params;
const product = await Product.findById(id);
res.status(200).json(product);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// create product
const createProduct = async (req, res) => {
try {
const product = await Product.create(req.body);
res.status(200).json(product);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// update product
const updateProduct = async (req, res) => {
try {
const { id } = req.params;
const product = await Product.findByIdAndUpdate(id, req.body);
if (!product) {
return res.status(404).json({ message: "Product not found." });
}
const updatedProduct = await Product.findById(id);
res.status(200).json(updatedProduct);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
const deleteProduct = async (req, res) => {
try {
const { id } = req.params;
const product = await Product.findByIdAndDelete(id);
if (!product) {
return res.status(404).json({ message: "Product not found." });
}
res.status(200).json({ message: "Product deleted successfully." });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = {
getProducts,
getProduct,
createProduct,
updateProduct,
deleteProduct,
};
index 파일에 있던 내용을 route와 controller로 분리하여 코드를 분산시킨 것이다. 내용을 분리하는 과정 자체가 폴더 구조가 되는 것이다.

이전에 킹슬리 형님이 제시하신 폴더 구조가 이해가 되는 시점이다,,,
More to read
프론트엔드와 백엔드 사이
HTTP 상태 코드는 프론트엔드에서 백엔드로 보냈던 요청의 수행 결과를 의미하는 일종의 약속이며, API를 구성하는 핵심 요소 중 하나입니다. 상태 코드와 관련하여, 백엔드는 잘 모르는 프론트엔드의 슬픈 사정이 있습니다.아래는 요청이 실패했음에도, 백엔드에서 상태 코드
JWT토큰 관리 방식 톺아보기
0. 들어가며 🎯 서비스에 접근하려는 사용자가 누구인지 확인하는 과정을 사용자 인증이라고 합니다. 인증된 사용자에게 주어진 권한을 확인하는 작업은 인가라고 부릅니다. 이번 글에서는 인가는 다루지 않습니다. 사용자 인증에는 많은 방식이 있지만, 오늘은 세션 인증 방
A2AA2A / MCP 멀티 에이전트 오케스트레이션
0. 들어가며 ✍️ Google for Developers에, 레스토랑 공급망 시나리오로 엮은 6대 프로토콜(MCP, A2A, UCP, AP2, A2UI, AG-UI)에 대한 가이드가 게시된 이후, MCP와 A2A부터 구현해 보는 것이 좋을 것 같다는 생각이 들었습니