๐ ์ถ๊ฐ routing ์ฒ๋ฆฌ
app.js์ ์ฝ๋ ์ถ๊ฐ
const router = require('./routes/index');
app.use('/', router);
/routes/index.js ์์ฑ
// @ts-check
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index');
});
module.exports = router;
/views/index.ejs ์์ฑ
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Index</title>
</head>
<body>
<h1>Hello, Express Service</h1>
<h2><a href="/users">Move to USER service</a></h2>
<h2><a href="/posts">Move to POST service</a></h2>
</body>
</html>
๐ res.status(undefined) ์๋ฌ๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด app.js์์ ์๋ฌ์ฝ๋ ์์
์ด๋์ ๋ฐ์ํ ๊ฒ์ธ์ง๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง ์๋ฒ์์ ๋ฌธ์ ์ด๋ฏ๋ก err ๊ฐ์ฒด์ statusCode๊ฐ ์์ผ๋ฉด 500์ ๋์ฐ๋๋ก ํจ
(ex. ejs ํ์ผ์์ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ)
app.use((err, req, res, next) => {
console.log(err.stack);
res.status(err.statusCode || 500);
res.send(err.message);
});
๐ ํ๋ก ํธ์ form ํ๊ทธ๋ก ๋ฐฑ์ ๋ฐ์ดํฐ ๋ณด๋ด๊ธฐ
๐ฉ Form
- action : ๋ณด๋ด๊ณ ์ ํ๋ ์ฃผ์ ๊ฐ
- method : ๋ณด๋ด๋ method ์ค์
- input์ name : ์๋ฒ์์ ๋ฐ์ ๋์ ํ๋ ๊ฐ
- button์ผ๋ก submit์ ํ๋ฉด ํด๋น ํผ์ ๋ด์ฉ์ ์ง์ ํ ๋ฐฉ์ + ์ฃผ์๋ก ์ ๋ฌํจ
<form action="/users" method="POST">
<div>
<label>ID</label>
<input type="text" name="id" />
</div>
<div>
<label>NAME</label>
<input type="text" name="name" />
</div>
<div>
<label>EMAIL</label>
<input type="email" name="email" />
</div>
<button type="submit">Submit</button>
</form>
๐ฉ body-parser: form์์ ์ ์ก๋ ์ ๋ณด๋ฅผ req.body์ ๋ด์์ obj๋ก ์ ๋ฌํด์ฃผ๋ ์ญํ
์ฌ์ฉํ์ง ์์ผ๋ฉด ๋ฐ์ดํฐ๋ฅผ body์ ๋ฃ์ ๋ค์ ์ธ์ฝ๋ฉ ์ฒ๋ฆฌ๊น์ง ํด์ค์ผ ํจ
(req.on('data', function(chunk) { body += chunk; });)
- [ํฐ๋ฏธ๋] npm install body-parser --save
- app.js์ ์ฝ๋ ์ถ๊ฐ
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
- url-encoded ์ต์ ์ ๋ฐ์ดํฐ๋ฅผ ๋ณํํ๋ฉด ํด๋น ๋ฐ์ดํฐ๋ฅผ json ํํ๋ผ๊ณ ์ ๋ฌ
- extended: true => query๋ก ๋ค์ด์จ ๋ฌธ์์ด์ ์ธ๋ถ ๋ชจ๋์ธ qs ๋ชจ๋๋ก ์ฒ๋ฆฌ(์ค์น ํ์, npm i qs)
- extended: false => express ๋ด์ฅ ๋ชจ๋์ธ queryString ๋ชจ๋๋ก ์ฒ๋ฆฌ, ์ค์ฒฉ๋ ๊ฐ์ฒด ํ์ฉ x
๐ฉ req.body ์ฒ๋ฆฌ
- form์์ ์ ๋ฌ๋ ์ ๋ณด๋ req.body๋ฅผ ํตํด ๋ค์ด์ด
- req.query ๊ฐ์ ์ ๋ฌํ์ง ์์๋ ๋น ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋๋ฐ ๋น ๊ฐ์ฒด๋ if๋ฌธ์์ true๋ฅผ ๋ฆฌํดํ๋ฏ๋ก ์์ธ ์ฒ๋ฆฌ ํ์
- ํ์๊ฐ์ ์ด ์๋ฃ๋๋ฉด ๋ค์ ํ์ ๋ชฉ๋ก ํ์ด์ง๋ฅผ ๋ณด์ฌ์ฃผ๋๋ก res.direct ์ฌ์ฉ
router.post('/', (req, res) => {
if (Object.keys(req.query).length > 0) {
if (req.query.id && req.query.name && req.query.email) {
const newUser = {
id: req.query.id,
name: req.query.name,
email: req.query.email,
};
USER.push(newUser);
res.redirect('/users');
} else {
const err = new Error('Unexpected query');
err.statusCode = 404;
throw err;
}
} else if (req.body) {
if (req.body.id && req.body.name && req.body.email) {
const newUser = {
id: req.body.id,
name: req.body.name,
email: req.body.email,
};
USER.push(newUser);
res.redirect('/users');
} else {
const err = new Error('Unexpected form Data');
err.statusCode = 404;
throw err;
}
} else {
const err = new Error('No data');
err.statusCode = 404;
throw err;
}
});
๐ form ์์ด ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ๋ฐฉ๋ฒ
๐ฉ XMLHttpRequest
- 1999๋ ์ ํด๋ผ์ด์ธํธ์์ ์๋ฒ ์ธก ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ธฐ ์ํด ํ์
- promise ๋ฑ์ ๊ธฐ๋ณธ์ผ๋ก ๋ด์ฅํ์ง ์๊ธฐ ๋๋ฌธ์ ์๋ฒ ํต์ ์ ๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ค๋ฉด ๋ฐ๋ก ์ฌ์ฉํด์ผํ๋ ๋ถํธํจ์ด ์์
๐ฉ JQuery
- 2006๋ ๋ฑ์ฅํ์ฌ DOM ๊ธฐ๋ฅ, ๋ฐ์ดํฐ ํต์ ๋ฑ ๋ค์ํ ๋ถ์ผ์์ ์ฌ์ฉ
- ES6 ๋ฌธ๋ฒ์ด ๋ฑ์ฅํ๊ธฐ ์ ๊น์ง๋ ์ฃผ๋ก JQuery๋ฅผ ํตํด ํต์
๐ฉ Fetch()
- ๋ธ๋ผ์ฐ์ ์์ ์๋ฒ ์ฌ์ด๋ ํต์ ์ ์ํด 2015๋ ES6์์ ์ถ๊ฐ๋ ๊ธฐ๋ฅ
- ๊ธฐ์กด์ XMLHttpRequest์ ๋ฌธ์ ์ ์ ๊ฐ์ ํ์ฌ(promise ๋ด์ฅ) ์๋ฒ ํต์ ์ฝ๋๋ฅผ ๋ฐฑ์๋ ์ฝ๋์ ๋น์ทํ๊ฒ ์งค ์ ์์
๐ฉ fetch๋ฅผ ์ด์ฉํ ์ญ์ ๊ธฐ๋ฅ ๊ตฌํ
- li ์์์ ์ญ์ ๋ฒํผ ์ถ๊ฐ(a ํ๊ทธ)
- a ํ๊ทธ์ onclick์ผ๋ก ์ญ์ ํจ์ ์ฐ๊ฒฐ => ํด๋น ํจ์์์ fetch๋ก ์ญ์ api ์์ฒญ
<li>
<p>id: <%= USER[i].id %></p>
<p>name: <%= USER[i].name %></p>
<p>email: <%= USER[i].email %></p>
<a href="" onclick="deleteUser('<%= USER[i].id %>');">์ญ์ </a>
</li>
- deleteUser(id) ํจ์ ๊ตฌํ
<script>
function deleteUser(id) {
fetch(`http://localhost:4000/users/${id}`, {
method: 'delete',
headers: {
'Content-type': 'application/json'
},
}).then((res) => {
location.reload();
})
}
</script>
๐ DBMS(DataBase Managemanet System): ๋ฐ์ดํฐ ๋ฒ ์ด์ค๋ฅผ ๊ด๋ฆฌํ๊ณ ์ด์ํ๋ SW
๐ฉ SQL(Structured Query Language): select, insert, update, delete ๊ฐ์ ์ธ์ด๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ์ธ์ด
๐ฉ ๊ด๊ณํ(SQL), Relational DBMS(RDBMS): SQL์ ์ฌ์ฉํ๋ DB, ํค์ ๊ฐ์ ๊ด๊ณ๋ฅผ ํ ์ด๋ธํ ์ํจ ์์น์ ํ ๋๋ก ๊ตฌ์ฑ
- ๋จผ์ ํ ์ด๋ธ์ด ๊ตฌ์ฑ๋๊ณ ํ ์ด๋ธ์ ๊ตฌ์กฐ์ ๋ง์ถ์ด ๋ฐ์ดํฐ๊ฐ ๋ค์ด๊ฐ๊ธฐ ๋๋ฌธ์ DB๋ฅผ ๊ตฌ์ฑํ๊ธฐ ์ ์ ์คํค๋ง๋ผ ๋ถ๋ฆฌ๋ DB์ ๊ตฌ์กฐ, ๊ด๊ณ, ์ ์ฝ ์ฌํญ์ ๋ํ ์ ์๊ฐ ํ์
- ์ฅ์ : ๊ตฌ์กฐํ๊ฐ ๋ช ํํด์ ์์ธ๊ฒ ์์, ๋ฐ์ดํฐ ์ ์ถ๋ ฅ ์๋๊ฐ ๋น ๋ฆ, ์ ๋ขฐ์ฑ์ด ๋์
- ๋จ์ : DB์ ๊ตฌ์กฐ ๋ณ๊ฒฝ์ด ์ด๋ ต๊ธฐ ๋๋ฌธ์ ๋น ๋ฐ์ดํฐ ๋ฑ์ ์ฌ์ฉ์ด ์ด๋ ค์(์๋ก์ด ํค๊ฐ ์ถ๊ฐ๋๋ฉด ์ ์ฒด ์คํค๋ง ๋ณ๊ฒฝ์ด ํ์)
๐ฉ ๋น๊ด๊ณํ(NoSQL): SQL์ ์ฌ์ฉํ์ง ์๋ ๋ชจ๋ DB
- ๋ฌธ์ํ, ๊ทธ๋ํํ, ํค๋ฐธ๋ฅํ, ์์ด๋ ์ปฌ๋ผํ...
- ํน์ ๋ชฉ์ ์ ๋ง๋ DB๊ฐ ์กด์ฌ
- ์ฅ์ : ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ํจ์จ์ , ๊ตฌ์กฐ ๋ณ๊ฒฝ์ด ์ฝ๊ณ ํ์ฅ์ฑ์ด ๋ฐ์ด๋จ, ๋ณต์กํ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ ํํ์ด ๊ฐ๋ฅ
- ๋จ์ : ๋ฐ์ดํฐ ์์ฒด๊ฐ ํฌ๋ฉด ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ์ผ๋ถ ์ฝ์ด์ ์ฒ๋ฆฌํด์ผ ํ๋ฏ๋ก ๋ฐ์ดํฐ๊ฐ ํฌ๋ฉด ์๋๊ฐ ์ ํ๋๋ ๋ฌธ์ ๋ฐ์
๐ฉ MongoDB(Humongous DB)
- ์ฅ์ : ๋ฐ์ดํฐ๋ฅผ ์ต์ํ JSON ํํ๋ก ์ฒ๋ฆฌ, ๊ตฌ์กฐ ๋ณ๊ฒฝ ์ฉ์ด, ๋์ ์ํ ํ์ฅ์ฑ, ์คํค๋ง ์ค๊ณ์ ์ ์ฐ์ฑ
- ๋จ์ : ํ์ค์ด ์์, ๋ฐ์ดํฐ๊ฐ ๊ตฌ์กฐํ ๋์ด ์์ง ์๊ธฐ ๋๋ฌธ์ ๋จ์ํ ๊ตฌ์กฐ์ ์ฟผ๋ฆฌ๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๊ณ ๋ฐ์ดํฐ์ ์ผ๊ด์ฑ ๋ฐ ์์ ์ฑ์ DB๊ฐ ์๋ App ๋ ๋ฒจ์์ ๊ด๋ฆฌํด์ค์ผ ํจ => ๋ฒ๊ทธ ๋ฐ์ ํ๋ฅ ๋์
- https://www.mongodb.com/ko-kr/cloud/atlas/efficiency ์์ ๋ก๊ทธ์ธ -> FREE db -> cluster ์์ฑ -> username/password -> ip ๋ฑ๋ก -> connect -> include full driver code example ์ฒดํฌ ํ ์ฝ๋ ๋ณต์ฌ
- routes/mongo.js ์์ฑ ํ ๋ถ์ฌ๋ฃ๊ธฐ
- [ํฐ๋ฏธ๋] npm i mongodb
- [ํฐ๋ฏธ๋] node routes/mongo.js
- mongodb ์ ์์ฉ ํจ์ + ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์ฑ(async, await)
// @ts-check
const { MongoClient, ServerApiVersion } = require('mongodb');
const uri =
'mongodb+srv://ebulsok:<password>@cluster0.dvpqw9g.mongodb.net/?retryWrites=true&w=majority';
const client = new MongoClient(uri, {
useNewUrlParser: true,
useUnifiedTopology: true,
serverApi: ServerApiVersion.v1,
});
async function main() {
await client.connect();
const users = client.db('KDT-1').collection('users');
await client.close();
}
main();
.insertOne({ }) : ํ๋์ ๋ํ๋จผํธ(๋ฐ์ดํฐ) ์ฝ์
.insertMany([{ }]) : ๋ง์ ๋ฐ์ดํฐ๋ฅผ ํ๊บผ๋ฒ์ ์ฝ์ (๋ฐฐ์ด์ ๋ด๊ธด ๊ฐ์ฒด ํํ๋ก ์ ๋ฌ ๋์ด์ผ ํจ)
.deleteOne({ }) : ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ฒซ ๋ํ๋จผํธ ํ๋๋ฅผ ์ญ์
.deleteMany([{ }]) : ๋ง์ ๋ฐ์ดํฐ๋ฅผ ํ๊บผ๋ฒ์ ์ญ์
.updateOne({ }, { $set: { }, }) : ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ฒซ ๋ํ๋จผํธ ํ๋๋ฅผ ์์
.updateMany({ }, { $set: { }, }) : ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ชจ๋ ๋ํ๋จผํธ๋ฅผ ์์
.findOne({ }) : ๊ฒ์ ์กฐ๊ฑด์ ๋ง์กฑํ๋ ์ฒซ ๋ํ๋จผํธ๋ฅผ ์ฐพ์์ ๊ฐ์ ๋ฐํ(๋ณ์์ ๋ฃ์ด์ ์ฒ๋ฆฌ/๋ฐ๋ก ์ถ๋ ฅํด์ผํจ)
.find([{ }]) : ์กฐ๊ฑด์ ๋ถํฉํ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ถ ์ฐพ์์ค
- ์ค์ ์ ์ธ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ๋ณด๋ค cursor ๊ฐ์ฒด๋ก ์ ์ฅ
- ๋ฆฌํด์ด ๋ ๋ await๋ฅผ ์ฌ์ฉํ์ง ์์
- find๋ก ์ฐพ์ ๊ฐ์ ์ถ๋ ฅํ๋ ค๋ฉด await์ ํจ๊ป forEach() ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผ ํจ
- ๋ฐ์ดํฐ๋ก ๋ณ๊ฒฝํ๋ ค๋ฉด await์ ํจ๊ป toArray() ๋ฉ์๋๋ฅผ ์ฌ์ฉ
๋น๊ต์/๋ ผ๋ฆฌ์
// db.์ปฌ๋ ์
๋ช
.find({์ฟผ๋ฆฌ: [{์กฐ๊ฑด1}, {์กฐ๊ฑด2}, ...]});
const data = users.find({
$and: [{ age: { $gte: 5 } }, { name: 'loopy' }],
});
await data.forEach(console.log);
'KDT > TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
9/16 TIL : cookie, HTTP session, passport (0) | 2022.09.20 |
---|---|
9/14 TIL : ๊ฒ์ํ ๊ธฐ๋ฅ์ MongoDB ์ ์ฉ, ์๋ฒ ๋ฐฐํฌ (0) | 2022.09.20 |
9/5 TIL : express๋ก API ๋ง๋ค๊ธฐ, view engine(EJS), express ํด๋ ๊ตฌ์กฐ (0) | 2022.09.18 |
9/2 TIL : ์ ๊ฐ ๊ตฌ๋ฌธ, yarn, postman, express router (0) | 2022.09.18 |
8/31 TIL : File-system(JS, Promise, async/await), Routing w/o framework (0) | 2022.09.18 |