๐Node JS๋ฅผ ์ฌ์ฉํ์ฌ Scrach์ ํ๋ ์ ์์ด REST Api ๊ตฌ์ถ
15719 ๋จ์ด nodejavascriptbeginnerswebdev
๐ฅ ์๋ฒ ์์ ๋ฐ ์คํ
์ฐ์ , node js์์ http ํจํค์ง๋ฅผ ๊ฐ์ ธ์ฌ ๊ฒ์
๋๋ค.๊ทธ๋ฆฌ๊ณ ์ฐ๋ฆฌ๋ ๊ทธ ์ค์์ createServer()
๋ฐฉ๋ฒ์ ํธ์ถํ ๊ฒ์ด๋ค. ์ด๊ฒ์ ์ฐ๋ฆฌ์๊ฒ http.Server
๋ฅ์ ์ค๋ก๋ฅผ ์ ๊ณตํ ๊ฒ์ด๋ค.์ดํ์ ์ฐ๋ฆฌ๋ listen()
ํด๋์ค ์ค๋ก์์ http.Server
๋ฐฉ๋ฒ์ ํธ์ถํ ๊ฒ์ด๋ค. ์ด ํด๋์ค ์ค๋ก๋ HTTP ์๋ฒ ํ์ง ์ฐ๊ฒฐ์ ์์ํ ๊ฒ์ด๋ค.๐.
const http = require('http');
const server = http.createServer();
const PORT = process.env.PORT || 5000;
server.listen(PORT, () => console.log(`Server listening on port ${PORT}!!!`));
http์ ๊ดํ์ฌ.createServer๏ผ๏ผ
http.createServer()
์ต์
๋งค๊ฐ ๋ณ์requestListener
๋ฅผ ์ฌ์ฉํฉ๋๋ค.HTTP ์๋ฒ ๋์์ ์ปดํจํฐ์ ํฌํธ๋ฅผ ๊ฐ์ฒญํ๊ณ ์์ฒญ์ ํ ๋๋ง๋ค ํจ์ RequestListener๋ฅผ ์คํํฉ๋๋ค.์ด๊ฒrequestListener
์ ์ฌ์ฉ์์ ์์ฒญ๊ณผ ์๋ต์ ์ฒ๋ฆฌํฉ๋๋ค.์ฌ๊ธฐrequestListener
์์ ์์ฒญ๊ณผ ์๋ต ๋งค๊ฐ ๋ณ์์ ์ ๊ทผํ ์ ์์ต๋๋ค.์ด ํจ์์์, ์ฐ๋ฆฌ๋ ๋ชจ๋ ์ ์ก ์์ฒญ์ req.url
์ req.method
๋ฅผ ๊ฒ์ฌํ ๋ค์, ์กฐ๊ฑด๋ถ๋ก ์
๋ฌด ๋
ผ๋ฆฌ๋ฅผ ์งํํ์ฌ, ๊ธฐ๋ํ๋ ์๋ต์ ์ฌ์ฉ์์๊ฒ ๋๋๋ ค์ค ๊ฒ์ด๋คโจ .
๐ฅณ CRUD ๊ธฐ๋ฐrestapi ๊ตฌ์ถ
์ด๋ก ๋ง์ผ๋ก๋ ์ถฉ๋ถํฉ๋๋ค. ์ด์ ๊ฐ๋จํ CRUD api๋ฅผ ๊ตฌ์ถํ์ฌ TODO๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ดํด๋ณด๊ฒ ์ต๋๋ค.Thisgithub ๋ฉ๋ชจ๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ๋งํฌ๋ก ์์ ํ ์๋ณธ ์ฝ๋๋ฅผ ์ป์ ์ ์์ต๋๋ค.์ฌ๊ธฐ ์๋ฅ ๋ ๊ฐ๊ฐ ํ์ํฉ๋๋ค.
๊ฐ๊ฐ data.js
๊ณผ todoController.js
์ด๋ค.todo.js
์์ ์ด ๊ฐ์ข์ ์ฌ์ฉํ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.๋๋ ์ด ๊ฐ์ข๋ฅผ ์ํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ ๊ฒ์ ์ถ๊ฐํด์ ์ผ์ ๋ณต์กํ๊ฒ ๋ง๋ค๊ณ ์ถ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.todoController.js
์์, ์ฐ๋ฆฌ๋ ์ด ๋ฐ์ดํฐ์ ๋ํด ์คํํ ์ ์๋ ๊ธฐ๋ฅ์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, id๋ฅผ ํตํด todo๋ฅผ ์ฐพ๊ฑฐ๋ ๋ชจ๋ ์ ์ฌํ todo๋ฅผ ์ป์ ์ ์์ต๋๋ค.๋๋ ์ด ๋ ํ์ผ์ ์์ ๋กญ๊ฒ ์กฐํํ ์ ์๋ค.\
์ฐ๋ฆฌ๋ TODO๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด ๋ค์ฏ ๊ฐ์ ๋
ธ์ ์ ๊ฐ์ง๊ณ ์์ ๊ฒ์ด๋ค.
const http = require('http');
const server = http.createServer();
const PORT = process.env.PORT || 5000;
server.listen(PORT, () => console.log(`Server listening on port ${PORT}!!!`));
์ด๋ก ๋ง์ผ๋ก๋ ์ถฉ๋ถํฉ๋๋ค. ์ด์ ๊ฐ๋จํ CRUD api๋ฅผ ๊ตฌ์ถํ์ฌ TODO๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์ดํด๋ณด๊ฒ ์ต๋๋ค.Thisgithub ๋ฉ๋ชจ๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ๋งํฌ๋ก ์์ ํ ์๋ณธ ์ฝ๋๋ฅผ ์ป์ ์ ์์ต๋๋ค.์ฌ๊ธฐ ์๋ฅ ๋ ๊ฐ๊ฐ ํ์ํฉ๋๋ค.
๊ฐ๊ฐ
data.js
๊ณผ todoController.js
์ด๋ค.todo.js
์์ ์ด ๊ฐ์ข์ ์ฌ์ฉํ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.๋๋ ์ด ๊ฐ์ข๋ฅผ ์ํด ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ ๊ฒ์ ์ถ๊ฐํด์ ์ผ์ ๋ณต์กํ๊ฒ ๋ง๋ค๊ณ ์ถ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.todoController.js
์์, ์ฐ๋ฆฌ๋ ์ด ๋ฐ์ดํฐ์ ๋ํด ์คํํ ์ ์๋ ๊ธฐ๋ฅ์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, id๋ฅผ ํตํด todo๋ฅผ ์ฐพ๊ฑฐ๋ ๋ชจ๋ ์ ์ฌํ todo๋ฅผ ์ป์ ์ ์์ต๋๋ค.๋๋ ์ด ๋ ํ์ผ์ ์์ ๋กญ๊ฒ ์กฐํํ ์ ์๋ค.\์ฐ๋ฆฌ๋ TODO๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ํด ๋ค์ฏ ๊ฐ์ ๋ ธ์ ์ ๊ฐ์ง๊ณ ์์ ๊ฒ์ด๋ค.
/api/todos
์ ๋ฐฉ๋ฒ: GET
- ๋ชจ๋ TODO์ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์ต๋๋ค./api/todos/:id
์ ๋ฐฉ๋ฒ: GET
- id๋ฅผ ํตํด todo์ ๊ฒฝ๋ก๋ฅผ ๊ฐ์ ธ์ต๋๋ค./api/todos/:id
์ ๋ฐฉ๋ฒ: PATCH
- todo id์ ๋ฐ๋ผ todo๋ฅผ ์
๋ฐ์ดํธํ๋ ๋ฃจํธ/api/todos/:id
์method: DELETE
- id๋ฅผ ํตํด todo๋ฅผ ์ญ์ ํ๋ ๋ฃจํธ/api/todos/:
์ ๋ฐฉ๋ฒ: POST
- ์ todo๋ฅผ ๋ง๋๋ ๋ฃจํธ์
๋๋ค.res
์ requestListener
๋งค๊ฐ ๋ณ์์ ์กด์ฌํ๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์์์ผ ํ๋ค.writeHead()
- HTTP ์ํ ์ฝ๋์ ์๋ต ํค๋ ์ปฌ๋ ์
์ ํด๋ผ์ด์ธํธ์ ๋ค์ ๋ณด๋
๋๋ค.์ํ ์ฝ๋๋ ์์ฒญํ ๊ฒฐ๊ณผ๋ฅผ ํ์ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.์๋ฅผ ๋ค์ด ๋ชจ๋ ์ฌ๋์ด ์ด์ ์ 404 ์ค๋ฅ๋ฅผ ๋ง๋ฌ๋๋ฐ, ์ด๊ฒ์ ํ์ด์ง๋ฅผ ์ฐพ์ ์ ์๋ค๋ ๊ฒ์ ๋ํ๋ธ๋ค.์์ ์๋ฒ๋ ์ฝ๋ 200์ ๋๋๋ ค ์ฑ๊ณต์ ํ์ํฉ๋๋ค.end()
- ์ด ๋ฐฉ๋ฒ์ ์๋ฒ์ ์ ํธ๋ฅผ ๋ณด๋ด์ ๋ชจ๋ ์๋ต ํค๋์ ๋ณธ๋ฌธ์ด ๋ฐ์ก๋์์์ ๋ํ๋ธ๋ค.์ด ์๋ฒ๋ ์ด ๋ฉ์์ง๊ฐ ์๋ฃ๋์๋ค๊ณ ์ฌ๊ฒจ์ผ ํฉ๋๋ค.๋ฐฉ๋ฒ๋ชจ๋ ์๋ต์ end () ๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค.์ด ๋ฐฉ๋ฒ์์, ์ฐ๋ฆฌ๋ ์ฐ๋ฆฌ๊ฐ ๋๋๋ ค ์ฃผ๊ณ ์ถ์ ๋ฐ์ดํฐ๋ฅผ ์๋ต์ผ๋ก ์ฌ์ฉ์์๊ฒ ์ ๋ฌํ ๊ฒ์ด๋ค.(1) ๋ชจ๋ ์ ๋ฌด ๋ ธ์ ์ ํ๋ณดํ๋ค.
์ฐ์ ์์ ์์ฒญ
url
๊ณผ method
๊ฐ ๊ฐ๊ฐ /api/todos
๊ณผGET
์ธ์ง ํ์ธํ๊ฒ ์ต๋๋ค.๋ง์ฝ ๊ทธ๋ ๋ค๋ฉด, ์ฐ๋ฆฌ๋ data.js
์ ๋์์ผ๋ก todoController.js
๋ชจ๋ ๋๊ธฐ ์ฌํญ์ ๊ฐ์ ธ์ค๊ณ , ๋ชจ๋ ๊ฒ์ด ์์กฐ๋กญ๋ค๋ฉด, ์ฐ๋ฆฌ๋ ์ํ ์ฝ๋๋ฅผ 200์ผ๋ก ์ค์ ํฉ๋๋ค. ์ด๊ฒ์ ์์ฒญ์ด ์ฑ๊ณตํ์์ ๋ํ๋
๋๋ค.์ฌ๊ธฐ์ ์ ๋ชฉContent-Type : application/json
์ ์ค์ ํ๋ฉด ํด๋ผ์ด์ธํธ๊ฐ ๋๋์์ค๋ ๋ด์ฉ์ ์ ํ์ด JSON ํ์์ด๋ผ๋ ๊ฒ์ ์๋ ค์ค๋๋ค.๋ชจ๋ ๋ฃจํธ์ ์์ฒญ์ ์ด ํค๋๋ฅผ ์ค์ ํ ๊ฒ์
๋๋ค. ๋ฐ์ดํฐ๋ฅผ JSON ๋ฌธ์์ด๋ก ๋ณํํ ๊ฒ์
๋๋ค.๊ทธ๋ฆฌ๊ณ ์์ฒญํ url
์ด๋ method
์ด ์ผ์นํ์ง ์์ผ๋ฉด, ์ํ ์ฝ๋๋ฅผ 404๋ก ์ค์ ํฉ๋๋ค. ์ด๊ฒ์ ์ฐพ์ ์ ์์์ ์๋ฏธํ๋ฉฐ, ๋ฃจํธ์์ ์ฐพ์ ์ ์๋ ๋ฉ์์ง๋ฅผ ์๋ต์ผ๋ก ๋ณด๋ผ ๊ฒ์
๋๋ค.const server = http.createServer(async (req, res) => {
if (req.url === '/api/todos' && req.method === 'GET') {
const todos = await Todo.findAll();
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(todos));
} else {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Route not found!' }));
}
});
๊ฐ๋ฐ ๊ณผ์ ์์ API๋ฅผ ํ
์คํธํ๊ธฐ ์ํด ์ํ๋ ๋๋ก ๋ชจ๋ ํด๋ผ์ด์ธํธ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.๋๋ ์ฐ์ฒด๋ถ๊ฐ ๋์ API๋ฅผ ํ
์คํธํ๋ ๊ฒ์ ๋์ฑ ์ข์ํ๋ค.์ด๋ค ํ๋ซํผ์์๋ ๊ตฌ์
ํ ์ ์์ต๋๋คhere\(2) id๋ฅผ ํตํด todo๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฃจํธ
์ด ๋ ธ์ ์ ๋ํด ์ฐ๋ฆฌ์ ์ ์ฐจ๋ ๊ฐ์ ๊ฒ์ด๋ค.์ ์ผํ ์ฐจ์ด์ ์, ์ฐ๋ฆฌ๋ ๋ชจ๋ todo๋ฅผ ์ป์ง ์๊ณ , ํ๋์ todo๋ฅผ ๊ฐ์ ธ์ ์๋ต์ ๋๋๋ ค๋ฐ๋๋ค๋ ๊ฒ์ด๋ค.์ด ๋ฃจํธ์ ๋์ ๋งค๊ฐ ๋ณ์ id๊ฐ ์์ต๋๋ค. ์ด๊ฒ์ ๋ฃจํธ ์์ฒด์ ์ ๋ฌ๋๊ณ ํน์ ํ todo ๋งค๊ฐ ๋ณ์๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐ ๋ฌ๋ ค ์์ต๋๋ค.
if (req.url.match(/\/api\/todos\/([a-z A-Z 0-9]+)/) && req.method === 'GET') {
try {
const id = req.url.split('/')[3];
const todo = await Todo.findById(id);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(todo));
} catch (error) {
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Todo not found!' }));
}
}
ํ
์คํธ ํ ๋ค์๊ณผ ๊ฐ์ ์๋ต์ด ์ ๊ณต๋ฉ๋๋ค.\(3) ๋๊ธฐ์ฌํญ id์ ๋ฐ๋ผ ๋๊ธฐ์ฌํญ์ ์ญ์ ํ๋ ๋ฃจํธ
์ด ๋ ธ์ ์์ ์ฐ๋ฆฌ๋ ๋จผ์
req.method
๊ฐ DELETE
์ธ์ง ํ์ธํ ๊ฒ์ด๋ค.\์ด ๋ฃจํธ๋ ์๊ธฐ ๋ฃจํธ์ ๊ฐ์ต๋๋ค. ์ ์ผํ ์ฐจ์ด์ ์ id์ ๋ฐ๋ผ todo๋ฅผ ์ญ์ ํ๊ณ , id๋ฅผ ํตํด ๊ฐ์ ธ์ค๋ ๊ฒ์ด ์๋๋ผ ์๋ต์ผ๋ก ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ๊ฒ์ ๋๋ค.
if (req.url.match(/\/api\/todos\/([a-z A-Z 0-9]+)/) && req.method === 'DELETE') {
try {
const id = req.url.split('/')[3];
await Todo.deleteById(id);
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Todo deleted successfully!!!' }));
} catch (error) {
console.log(error);
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ message: 'Todo not found!' }));
}
}
ใ์ฐ์ฒด๋ถใ์์ ํ
์คํธํ ํ์ด๋ฒ์ ์ด๋ ๊ฒ.๋๋จธ์ง ๋ ๋ ธ์ , ์ฆ ํ๋๋ todo๋ฅผ ๋ง๋๋ ๋ฐ ์ฌ์ฉ๋๊ณ , ๋ค๋ฅธ ํ๋๋ todo๋ฅผ ์ ๋ฐ์ดํธํ๋ ๋ฐ ์ฌ์ฉ๋๋์ง ์์๋ณด๋ ค๋ฉดsatishnaikawadi.me
๋๋ ๋ํฌ๋ค์ด ์ ์ด๋ ์ด๋ ์ ๋์ ๋ด๊ฐ ์ด ๋ฌธ์ฅ์์ ํด์ํ ๋ด์ฉ์ ์ดํดํ๊ธฐ๋ฅผ ๋ฐ๋๋ค๐. ๊ถ๊ธํ ๊ฒ์ด ์์ผ๋ฉด ์ธ์ ๋ ์ง ๋ฌผ์ด๋ณด์ธ์.
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐Node JS๋ฅผ ์ฌ์ฉํ์ฌ Scrach์ ํ๋ ์ ์์ด REST Api ๊ตฌ์ถ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/satishnaikawadi2001/build-rest-api-with-node-js-without-any-frameworks-from-scrach-3c6mํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค