NodeJs(4)

๊น€์œ ๋‹ดยท2024๋…„ 1์›” 22์ผ

html/css/js

๋ชฉ๋ก ๋ณด๊ธฐ
7/13
post-thumbnail

๐Ÿ‘จโ€๐Ÿ’ป ์ค‘์š” ํŒŒ์ผ ์„ค๋ช…

app.js : node.js๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„ ์ฝ”๋“œ๋ฅผ ์ ์–ด๋†“๋Š” ๊ณณ
restaurants.json : ์‹๋‹น ์ •๋ณด๋“ค์„ ์ €์žฅํ•ด๋†“์€ ํŒŒ์ผ(์‹๋‹น๋“ค์€ ์ด๋ฆ„, ์ฃผ์†Œ๋“ฑ์„ ๊ฐ€์ง„ ๊ฐ์ฒด๋กœ์„œ ์ €์žฅ๋œ๋‹ค.)
restaurant-item.ejs: ejs์˜ include ๊ธฐ๋Šฅ์„ ํ†ตํ•ด restaurants.ejs์˜ ์‹๋‹น ์ถœ๋ ฅ ๋‚ด์šฉ์„ ๋ฌถ์–ด๋‘” ๊ฒƒ
404.ejs: page not found ํ‘œ์‹œํ•˜๋Š” ํŽ˜์ด์ง€

๐Ÿ‘จโ€๐Ÿ’ป Status Code

์ €๋ฒˆ๊นŒ์ง€ ์ž˜๋ชป๋œ url ํ˜น์€ ์—†๋Š” ์‹๋‹น id๋ฅผ ์ฐพ๋Š”๋‹ค๋ฉด 404.ejs๋ฅผ ๋„์šฐ๋Š” ๊ฒƒ์„ ๊ธฐ์–ตํ•  ๊ฒƒ์ด๋‹ค.
ํ•˜์ง€๋งŒ 404.ejs๊ฐ€ ๋–ด์„ ๋•Œ, ๊ฐœ๋ฐœ์ž ๋„๊ตฌ๋ฅผ ํ†ตํ•ด status code๋ฅผ ๋ณด๋ฉด 404๊ฐ€ ์•„๋‹ ๊ฒƒ์ด๋‹ค.

์ด๋Ÿฐ ๊ฒƒ๋„ error ์ฝ”๋“œ์™€ ์ผ์น˜์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค.
๊ทธ ๋ฐฉ๋ฒ•์€ ์ด ํŽ˜์ด์ง€๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ, status๋„ ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋˜๋Š”๋ฐ

res.render("404");
res.status(404).render("404");

์›๋ž˜ ์œ„์—์„œ ๋ฐ‘์˜ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ๋ฉด status๋„ 404๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋œ๋‹ค.
๋ญ ๋ณด์ด์ง€ ์•Š๋Š” ๋ถ€๋ถ„์ด๋‹ˆ๊นŒ ํฌ๊ฒŒ ์ค‘์š”์„ฑ์„ ๋ชป๋А๋‚„ ์ˆ˜๋„ ์žˆ๋Š”๋ฐ ์ด๋Ÿฐ ๋””ํ…Œ์ผ๋“ค์ด ๋‚˜์ค‘์— ํ”„๋กœ์ ์ด ์ปค์กŒ์„ ๋•Œ, ์ŠคํŒŒ๊ฒŒํ‹ฐ๋ฉด ๊ฐ™์€ ํ”„๋กœ์ ํŠธ๊ฐ€ ์•„๋‹ˆ๋ผ ์ž˜ ๊ตฌ์กฐํ™”, ์ •๋ฆฌ๋œ ํ”„๋กœ์ ํŠธ๋กœ ๋ณด์ด๊ฒŒ ํ• ๊บผ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

๐Ÿ‘จโ€๐Ÿ’ป .JS ํด๋” ๊ฐ„ ์ƒํ˜ธ์ž‘์šฉ

app.js์—์„œ ํ•จ์ˆ˜๋“ค์—์„œ ๊ฒน์น˜๋Š” ๋ถ€๋ถ„๋“ค์ด ์žˆ๋‹ค ๋ฐ”๋กœ

  1. restaurant.json ํŒŒ์ผ์—์„œ ๋ฐ์ดํ„ฐ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ฝ”๋“œ
const filePath = path.join(__dirname,"..", "data", "restaurants.json");
const fileData = fs.readFileSync(filePath);
const storedRestaurants = JSON.parse(fileData);
  1. ํŒŒ์ผ์—๋‹ค๊ฐ€ ์ƒˆ๋กœ์šด ์‹๋‹น ๊ฐ์ฒด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.
fs.writeFileSync(filePath, JSON.stringify((storableRestaurants)));

app.js๋ฅผ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์ด ๋‘ ๊ฐœ์˜ ์ฝ”๋“œ๋ฅผ ๋”ฐ๋กœ ์ƒˆ๋กœ์šด'util/restaurant-data.js' ํŒŒ์ผ์— ์ •๋ฆฌํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

const fs = require("fs");
const path = require("path");

const filePath = path.join(__dirname,"..", "data", "restaurants.json");

function getStoredRestaurants() {

	const fileData = fs.readFileSync(filePath);
	const storedRestaurants = JSON.parse(fileData);
	
	return storedRestaurants;
}

function storeRestaurants (storableRestaurants){
	fs.writeFileSync(filePath, JSON.stringify((storableRestaurants)));
}

module.exports={
	getStoredRestaurants: getStoredRestaurants,
	// ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•  ์ด๋ฆ„: ์ด ํŒŒ์ผ์—์„œ ํ•จ์ˆ˜ ์ด๋ฆ„
	storeRestaurants: storeRestaurants
}  

์ „์ฒด ์ฝ”๋“œ๋Š” ์ด์™€ ๊ฐ™์€๋ฐ ํ•˜๋‚˜์”ฉ ์‚ดํŽด๋ณด์ž.

const fs = require("fs");
const path = require("path");

๋ฐ‘์—์„œ fs์™€ path๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ์— fs์™€ path๋ฅผ ๋ถˆ๋Ÿฌ์™€ ์ฃผ๋Š” ๊ฒƒ์€ ๋‹น์—ฐํ•œ ์ผ์ด๋‹ค.

const filePath = path.join(__dirname,"..", "data", "restaurants.json")

์ด๊ฑด getStoredRestaurants, storeRestaurants ํ•จ์ˆ˜ ๋‘ ๊ฐœ ์‚ฌ์šฉํ•˜๊ธฐ์— ์ „์—ญ์œผ๋กœ ๋นผ์ฃผ์—ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  util์ด๋ž€ ํŒŒ์ผ ์•ˆ์— ์žˆ๊ธฐ์— ์œ„๋กœ ์˜ฌ๋ผ๊ฐ€์„œ app.js๋ฅผ ์ฐพ์•„์•ผ ํ•œ๋‹ค.
๊ทธ๋ž˜์„œ ์ƒ์œ„ ํด๋”๋กœ ์˜ฌ๋ผ๊ฐ€๋Š” ".."์„ ์ถ”๊ฐ€ํ•œ ๊ฒƒ์ด๋‹ค.

module.exports={
	getStoredRestaurants: getStoredRestaurants,
	// ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•  ์ด๋ฆ„: ์ด ํŒŒ์ผ์—์„œ ํ•จ์ˆ˜ ์ด๋ฆ„
	storeRestaurants: storeRestaurants
}  

์ด๊ฒŒ ๋‚˜๋Š” ์ œ์ผ ํฅ๋ฏธ๋กœ์› ๋Š”๋ฐ, ์ด ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜๋“ค์„ ์ •ํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค.
๋‚˜๋Š” ๋‹ค app.js์—์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋‹ˆ ๋ชจ๋‘ ์ ์—ˆ๊ณ  ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•  ํ•จ์ˆ˜ ์ด๋ฆ„๊ณผ ์‹ค์ œ ์ด ํŒŒ์ผ์—์„œ ํ•จ์ˆ˜ ์ด๋ฆ„์„ ์ฝœ๋ก ์„ ๋‘๊ณ  ์ ์–ด์ฃผ๋ฉด ๋œ๋‹ค.

์ž ๊ทธ๋Ÿผ app.js์—์„œ ์ด ํ•จ์ˆ˜๋“ค์„ ์–ด๋–ป๊ฒŒ ๋ถˆ๋Ÿฌ์˜ฌ๊นŒ?

const resData = require("./util/restaurant-data");

app.post("/recommend", function(req, res) {
	const restaurant = req.body; //object save
	restaurant.id = uuid.v4();
	const restaurants = resData.getStoredRestaurants();
	
	restaurants.push(restaurant);
	
	resData.storeRestaurants(restaurants);
	
	res.redirect("/confirm");
	
});

๋‹ค๋ฅธ ํŒจ์บ์ง€์ฒ˜๋Ÿผ require๋กœ ๋ถˆ๋Ÿฌ์˜ค๋˜ ์•ˆ์— ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋„ฃ๊ณ  ํ•จ์ˆ˜๋Š” ๊ฐ€์ ธ์˜จ ๊ฐ์ฒด์— .์„ ๋ถ™์ด๊ณ  ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿ‘จโ€๐Ÿ’ป Routes ๋ถ„๋ฆฌ

ํ•œ ์ค‘์‹ฌ jsํŒŒ์ผ์— ๋„ˆ๋ฌด ๋งŽ์€ routes๋“ค์ด ์žˆ๋‹ค๋ฉด, ์ด ๋˜ํ•œ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๊ตฌ์กฐ์ƒ ๋” ๊น”๋”ํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ routes๋“ค์„ ๋นผ์„œ

const express = require("express");
const uuid =require("uuid");

const resData = require("../util/restaurant-data");

const router = express.Router();

router.get("/restaurants", function(req, res) { 
	const storedRestaurants = resData.getStoredRestaurants();
	
	res.render("restaurants", { numberOfRestaurants: storedRestaurants.length, 
							   restaurants : storedRestaurants})
} );

router.get("/restaurants/:id", function (req, res) {
	const restaurantId = req.params.id;
	
	const storedRestaurants = resData.getStoredRestaurants();
	
	for(const restaurant of storedRestaurants) {
		if(restaurant.id== restaurantId) {
			return res.render("restaurant-detail", {restaurant: restaurant});
		}
	}
	
	res.status(404).render('404');
	
});

router.get("/recommend", function(req, res) {
	res.render("recommend");
} );

router.post("/recommend", function(req, res) {
	const restaurant = req.body; //object save
	restaurant.id = uuid.v4();
	const restaurants = resData.getStoredRestaurants();
	
	restaurants.push(restaurant);
	
	resData.storeRestaurants(restaurants);
	
	res.redirect("/confirm");
	
});

router.get("/confirm", function(req, res) {
	res.render("confirm");
} );

module.exports = router;

์ด๋Ÿฐ ์‹์œผ๋กœ ๋ถ„๋ฆฌํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

const express = require("express");
const router = express.Router();

express๋Š” ๋ฉ”์ธ ํŒŒ์ผ์—์„œ๋งŒ ์‹คํ–‰ํ•˜๊ธฐ์— express()๊ฐ€ ์•„๋‹ˆ๋ผ ์œ„์™€ ๊ฐ™์ด ์•„์›ƒ์†Œ์‹ฑํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

module.exports = router;

๊ทธ๋ฆฌ๊ณ  ์œ„์—์„œ๋„ ํ–ˆ๋Š”์ด ์ด๊ฑธ ๋ฉ”์ธ ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ export ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋ฉ”์ธ ํŒŒ์ผ์—์„œ๋Š”

const restaurantRoutes = require("./routes/restaurants");
app.use("/", restaurantRoutes);

์ด์™€ ๊ฐ™์ด ํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค์Œ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ํ†ตํ•ด์„œ ์ด ํŒŒ์ผ์„ ์“ฑ ํ›‘๊ฒŒ ํ•˜๋ฉด ๋œ๋‹ค.
๋‚ด๊ฐ€ ํ›‘๋Š”๋‹ค๋Š” ํ‘œํ˜„์„ ์‚ฌ์šฉํ•œ ์ด์œ ๋Š” "./routes/restaurants" ํŒŒ์ผ์„ ๋“ค์–ด๊ฐ”๋‹ค๊ฐ€ ํ•ด๋‹น๋˜๋Š” ๊ฒŒ ์—†์œผ๋ฉด ๋‹ค์‹œ ๋‚˜์™€์„œ ๋ฉ”์ธ ํŒŒ์ผ์—์„œ ๋‚˜๋จธ์ง€ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ฃผ์˜
์ฝ”๋“œ๋ฅผ ์˜ฎ๊ธฐ๋ฉด์„œ require ํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ๋“ค ์ž˜ ์ฑ™๊ธฐ๊ณ  ํŒŒ์ผ ์ƒ๋Œ€๊ฒฝ๋กœ ๋ฐ”๋€Œ๋‹ˆ ๊ทธ๊ฒƒ๋„ ์ž˜ ์ˆ˜์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค.

๐Ÿ‘จโ€๐Ÿ’ป Query Parameter

<form action="/restaurants" method="GET">
	<input type="hidden" value="<%= nextOrder %>" name="order">
	<button class="btn">Change Order</button>
</form>

์ด์™€ ๊ฐ™์ด html ์ฝ”๋“œ์— ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค๊ณ  ํ•ด๋ณด์ž.
๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด url ๋’ค์—๋Š”

?order=nextOrder

์ด๋ ‡๊ฒŒ ์ฟผ๋ฆฌ๊ฐ€ ๋ถ™๋Š”๋‹ค.(์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•ญ์ƒ ?๊ธฐํ˜ธ๋ฅผ ํ†ตํ•ด "์ฃผ ๊ฒฝ๋กœ"์™€ ๋ถ„๋ฆฌ๋จ)
์ด๊ฑธ ์ด์šฉํ•ด์„œ ๊ธฐ๋Šฅ๋“ค์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ € ๋ฒ„ํŠผ์ด sorting์„ ์˜ค๋ฆ„์ฐจ์ˆœ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ฆฌํ•˜๋Š” ๋ฒ„ํŠผ์ด๋ผ๋ฉด

restaurant.js์—

router.get("/restaurants", function(req, res) { 
	let order = req.query.order;
	let nextOrder = "desc";
	
	if(order !== "asc" && order !== "desc") {
		order="asc";
	}
	
	if(order === "desc"){
		nextOrder="asc";
	}
	
	const storedRestaurants = resData.getStoredRestaurants();
	
	storedRestaurants.sort(function(resA, resB) {
		if((order === "asc" && resA.name > resB.name)||
		   (order === "desc" && resB.name > resA.name)){
			return 1;
		}
		return -1;
	});
	
	res.render("restaurants", {
		numberOfRestaurants: storedRestaurants.length, 
		restaurants : storedRestaurants,
		nextOrder: nextOrder
	})
} );

์ด๋Ÿฐ ์‹์œผ๋กœ ํ•ด์„œ

let order = req.query.order;

์ฟผ๋ฆฌ๋ฅผ ์žก์•„์„œ(?) ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ๊ธฐ๋Šฅ๋“ค์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ‘จโ€๐Ÿ’ป ๋А๋‚€์ 

์ •๋ง ๊ตฌ์กฐํ™”๋ฅผ ํ•˜๋‹ˆ ๊น”๋”ํ•ด์ง€๋Š” ๊ฒƒ์ด ํ™•์—ฐํžˆ ๋ณด์ธ๋‹ค.
๋ฌผ๋ฃฌ ๋ชจ๋ฅด๋Š” ์‚ฌ๋žŒ๋“ค์€ ํด๋”์™€ ํŒŒ์ผ์ด ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ์ด ๋” ์ง€์ €๋ถ„ํ•ด๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ํด๋”, ํŒŒ์ผ์˜ ์ •์ฒด์„ฑ์™€ ์—ญํ• ์„ ๊ฐ•ํ™”์‹œ์ผœ์คŒ์œผ๋กœ ๋”์šฑ ๋ณด๊ธฐ ํŽธํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ํ™•์‹คํžˆ ๋А๊ปด์ง„๋‹ค.
๋‚ด๊ฐ€ ํ˜ผ์ž ํ”„๋กœ์ ํŠธํ•  ๋•Œ๋„ ์ด์™€ ๊ฐ™์ด ๊น”๋”ํ•˜๊ธฐ๋ฅผ.. ใ…Ž

profile
์ž˜ํ•˜์ง„ ๋ชปํ• ์ง€์–ธ์ • ๊พธ์ค€ํžˆ ํ•˜๋Š” ๊ฐœ๋ฐœ์ž:)

0๊ฐœ์˜ ๋Œ“๊ธ€