์ง๊ธ๊น์ง๋ HTTP ๋ชจ๋์ ์ฌ์ฉํ์ฌ ์ง์ ์๋ฒ๋ฅผ ๋ง๋ค๊ณ ๋ผ์ฐํ ์ ๊ตฌํํด ๋ณด์๋ค. ํ์ง๋ง ๋งค๋ฒ ์ด๊ฑธ ์ง์ ๋ค ๋ง๋ค์ด์ผ ํ๋? ์๊ฐ์ด ๋ค์๋ค.
Express.js๋ ์ด๋ฐ ์์ ์ ๋ ํจ์จ์ ์ผ๋ก ํ ์ ์๊ฒ ๋์์ฃผ๋ ํ๋ ์ ์ํฌ์ด๋ค. ์ค๋์ Express.js ๋ฅผ ์์๋ณด๊ณ , Express.js๋ฅผ ํ์ฉํ์ฌ REST API๋ฅผ ๋ง๋๋ ์ค์ต์ ํด๋ณด์๋ค.
๐คExpress
Express๋?
Node.js ํ๊ฒฝ์์ ์น ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ API๋ฅผ ๋น ๋ฅด๊ฒ ๋ง๋ค ์ ์๋๋ก ๋์์ฃผ๋ ๊ฒฝ๋ ์น ํ๋ ์์ํฌ
Express ๋ HTTP ๋ชจ๋
์์์ ๋์ํ๋ฉฐ, ๋ ์ง๊ด์ ์ธ ๋ผ์ฐํ
, ๋ฏธ๋ค์จ์ด ์ฒ๋ฆฌ, ๋ค์ํ ์๋ต ๋ฉ์๋ ๋ฑ์ ์ ๊ณตํ๋ค.
ํน์ง
- ๊ฐ๊ฒฐํ ๋ฌธ๋ฒ: ๋ผ์ฐํ ๊ณผ ์๋ต ์ฒ๋ฆฌ ์ฝ๋๊ฐ ๊ฐ๋จ
- ๋ฏธ๋ค์จ์ด ๊ธฐ๋ฐ: ์์ฒญ ํ๋ฆ์ ํ์ํ ๊ธฐ๋ฅ๋ค์ ๋จ๊ณ๋ณ๋ก ์ฝ์
- RESTful API ์ค๊ณ์ ์ต์ ํ: ๋ค์ํ HTTP ๋ฉ์๋ ์ฒ๋ฆฌ์ ์ ๋ฆฌ
- ํ๋ถํ ์ํ๊ณ: ๋ค์ํ ๋ฏธ๋ค์จ์ด์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฝ๊ฒ ํตํฉ ๊ฐ๋ฅ
Express๋ npm์ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ ์ค์นํ ์ ์๋ค.
npm i express
Express์ Node.js HTTP ๋ชจ๋์ ์ฐจ์ด์
Node.js์ http.CreateServer()
๋ฐฉ์์ ๋ชจ๋ ์์ฒญ์ ๋ํด if๋ฌธ์ด๋ switch ๋ฌธ์ผ๋ก ๋ถ๊ธฐํ๋ฉฐ, ๋ผ์ฐํ
์ ์ง์ ๊ตฌํํด์ผ ํ๋ค.
๋ฐ๋ฉด, Express๋ ์๋์ฒ๋ผ ํจ์ฌ ๊ฐ๊ฒฐํ๊ฒ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค.
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.send("Hello World");
});
app.listen(3000);
express()
ํธ์ถ ๊ฒฐ๊ณผ๋ฅผapp
์ ๋ด๋๋ค.app
๊ฐ์ฒด๋ ์๋ฒ ์์ฒด๋ผ๊ณ ๋ณด์๋ ๋ฌด๋ฐฉํ๋ค.app.listen()
์ผ๋ก ํฌํธ๋ฅผ ์ง์ ํ์ฌ ์๋ฒ๋ฅผ ์คํํ๋ค.- ๋ผ์ฐํ
์
app.get()
๋ฑ์ผ๋ก ๊ฐํธํ๊ฒ ๊ตฌํํ ์ ์๋ค.
Express REST API ์ค์ต
์๋๋ ๊ฐ๋จํ REST API ๋ผ์ฐํ ์์ ์ด๋ค.
app.get("/", (req, res) => {
res.send("Hello World");
});
app.get("/test", (req, res) => {
res.send("TEST SUCCESS");
});
app.get("/test/1", (req, res) => {
res.send("One!!");
});
app.get()
์ ํด๋ผ์ด์ธํธ๊ฐ ํน์ URL์ GET ์์ฒญ์ ๋ณด๋์ ๋ ์คํํ ์ฝ๋ฐฑ ํจ์๋ฅผ ๋ฑ๋กํ๋ ๋งค์๋์ด๋ค.- URL ๊ฒฝ๋ก๋ณ๋ก ๋ผ์ฐํธ๋ฅผ ์ ์ํ๊ณ , ์์ฒญ์ด ๋ค์ด์ค๋ฉด ํด๋น ์ฝ๋ฐฑ ํจ์๋ฅผ ์คํํ๋ค.(๋ฌธ์์ด ์๋ต)
- ์ด ์ฝ๋ฐฑ์
(req, res)
๋ฅผ ์ธ์๋ก ๋ฐ์ ์์ฒญ๊ณผ ์๋ต์ ๋ค๋ฃฌ๋ค.
app.listen()์ ์์น๋ ์ค์ํ ๊น?
๊ฒฐ๋ก ๋ถํฐ ๋งํ๋ฉด ์๋๋ค.
app.listen(3000);
listen()
์ ํฌํธ ๋ฒํธ๋ฅผ ์ค์ ํ๊ณ ์๋ฒ๋ฅผ ์คํํ๋ ํจ์์ผ ๋ฟ์ด๋ค. ์ฝ๋ ์๋จ์ ์๋ , ํ๋จ์ ์๋ ์๊ด์์ด ์ ์ ์๋ํ๋ค.
โญ ๋ชจ๋ ๋ผ์ฐํธ์ ๋ฏธ๋ค์จ์ด๊ฐ ์ ์๋ ์ดํ listen()์ ํธ์ถํด์ผ ๋ชจ๋ ์์ฒญ ํธ๋ค๋ฌ๊ฐ ์ค๋น๋ ์ํ์์ ์๋ฒ๊ฐ ์คํ๋๋ค.
โ์ค๋ฅ: ERR_HTTP_HEADERS_SENT
์ฌ๋ฌ๊ฐ์ ์๋ต์ ํ
์คํธ ํด๋ณด๊ธฐ ์ํด, res.send()
๋ฅผ ๋ ๋ฒ ์ฌ์ฉํด๋ณด์๋ค.
app.get('/product/1', function(res, req){
res.send('node.js๋ฅผ ๋ฐฐ์๋ณด์(์ฑ
) 20000์');
res.send(20000);
})
์ฝ๋๋ฅผ ์คํํด๋ณด๋, ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (node:_http_outgoing:659:11)
at ServerResponse.header (c:\Users\monic\OneDrive\๋ฐํ ํ๋ฉด\programmers\expressPractice\node_modules\express\lib\response.js:684:10)
at ServerResponse.contentType (c:\Users\monic\OneDrive\๋ฐํ ํ๋ฉด\programmers\expressPractice\node_modules\express\lib\response.js:514:15)
at ServerResponse.send (c:\Users\monic\OneDrive\๋ฐํ ํ๋ฉด\programmers\expressPractice\node_modules\express\lib\response.js:136:14)
at c:\Users\monic\OneDrive\๋ฐํ ํ๋ฉด\programmers\expressPractice\express_demo.js:23:7
at Layer.handleRequest (c:\Users\monic\OneDrive\๋ฐํ ํ๋ฉด\programmers\expressPractice\node_modules\router\lib\layer.js:152:17)
at next (c:\Users\monic\OneDrive\๋ฐํ ํ๋ฉด\programmers\expressPractice\node_modules\router\lib\route.js:157:13)
at Route.dispatch (c:\Users\monic\OneDrive\๋ฐํ ํ๋ฉด\programmers\expressPractice\node_modules\router\lib\route.js:117:3)
at handle (c:\Users\monic\OneDrive\๋ฐํ ํ๋ฉด\programmers\expressPractice\node_modules\router\index.js:435:11)
at Layer.handleRequest (c:\Users\monic\OneDrive\๋ฐํ ํ๋ฉด\programmers\expressPractice\node_modules\router\lib\layer.js:152:17)
ERR\_HTTP\_HEADERS\_SENT
์ค๋ฅ๋ ์๋ต ํค๋๊ฐ ์ด๋ฏธ ํด๋ผ์ด์ธํธ์๊ฒ ์ ์ก๋ ํ์ ๋ค์ ํค๋๋ฅผ ์ค์ ํ๋ ค ํด์ ๋ฐ์ํ ์ค๋ฅ์ด๋ค. ์ด๋ฏธ /product/1
๋ผ์ฐํธ์์ res.send()
๋ฅผ ํธ์ถํ๋๋ฐ, ๋ ๋ฒ์งธ ํธ์ถํ๋ ค๊ณ ํ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ์ด๋ค.
โญ express์์๋ ํ๋์ ์์ฒญ์ ๋ํด res.send() ๋ฅผ ํ ๋ฒ๋ง ํธ์ถํด์ผ ํ๋ค. ๋ง์ฝ ์ฌ๋ฌ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๋ฉด, ๊ฐ์ฒด ํํ๋ก ๋ฌถ์ด ํ๋ฒ์ ์ ๋ฌํ๋ค.
๐๊ฐ์ฒด์ JSON
๊ฐ์ฒด๋?
์์ฑ(key)์ ๊ฐ(value)์ ์์ผ๋ก ๊ตฌ์ฑ๋ ๋ฐ์ดํฐ ์งํฉ
let book = {
title: "Node.js๋ฅผ ๊ณต๋ถํด๋ณด์",
price: 20000,
description: "๋
ธ๋๋ฅผ ๋ฐฐ์๋ณด์",
};
book.title ๋ฑ์ผ๋ก ์ ๊ทผ ๊ฐ๋ฅํ๋ฉฐ, ๊ตฌ์กฐ์ ์ธ ๋ฐ์ดํฐ ํํ์ ์ ํฉํ ์๋ฃํ์ด๋ค.
JSON์ด๋?
javascript Object Notation, ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ๊ธฐ๋ฐ์ผ๋ก ํ ๋ฐ์ดํฐ ๊ตํ ํ์
์น์์ ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ๋ ์ฃผ๋ก ์ฌ์ฉ๋๋ค. ๋ฌธ์์ด ํํ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๊ธฐ ๋๋ฌธ์ ์ง๋ ฌํ/์ญ์ง๋ ฌํ ์์ ์ด ํ์ํ๋ค.(JSON.stringify(), JSON.parse())
ํญ๋ชฉ | ์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด | JSON |
---|---|---|
key | ๋ฐ์ดํ ์์ด ์ฌ์ฉ ๊ฐ๋ฅ | ์๋ฐ์ดํ๋ก ๊ฐ์ธ์ผ ํจ. |
value type | ํจ์, ์ฌ๋ณผ ๋ฑ ํฌํจ ๊ฐ๋ฅ | ๋ฌธ์์ด, ์ซ์, ๋ฐฐ์ด, ๊ฐ์ฒด๋ง ํ์ฉ |
โญres.send() vs res.json()
res.send()
๋ชจ๋ ํ์ ์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ์ ์๋ ๋ฒ์ฉ ์๋ต ๋ฉ์๋
/**
* Send a response.
*
* Examples:
*
* res.send(new Buffer('wahoo'));
* res.send({ some: 'json' });
* res.send('<p>some html</p>');
* res.status(404).send('Sorry, cant find that');
*/
send: Send<ResBody, this>;
- ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ฒด๋ฅผ ๋ฌธ์์ด(JSON)๋ก ์๋ ๋ณํํด์ ์๋ตํ๋ค.
- HTML, ๋ฒํผ, ๋ฌธ์์ด ๋ฑ ๋ค์ํ ํ์ ์ ์ก์ด ๊ฐ๋ฅํ๋ค.
res.json()
JSON ์ ์ฉ ์๋ต ๋ฉ์๋
/**
* Send JSON response.
*
* Examples:
*
* res.json(null);
* res.json({ user: 'tj' });
* res.status(500).json('oh noes!');
* res.status(404).json('I dont have that');
*/
json: Send<ResBody, this>;
- ๋ช ํํ๊ฒ JSON ํ์์ผ๋ก ์๋ตํ๋ค.
- ๋ฐ์ดํฐ ๊ตํ์ด ํ์ํ REST API ๊ฐ๋ฐ ์์๋ ๊ฐ๋ ์ฑ๊ณผ ๋ช ํ์ฑ ์ธก๋ฉด์์ ๊ถ์ฅ๋๋ค!
๐ํ๋ผ๋ฏธํฐ ๋ฐ์์ ๋์ ์ผ๋ก ์ฒ๋ฆฌํ๊ธฐ
๋ผ์ฐํธ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์๋์ฒ๋ผ ์์ฑํ๋ค๋ฉด /product/1
์ ๋ํ ์ฒ๋ฆฌ๋ง ๊ฐ๋ฅํ๋ค.
app.get("/product/1", (req, res) => {
res.json({
title: "Node.js๋ฅผ ๊ณต๋ถํด๋ณด์",
price: 20000,
description: "๋
ธ๋๋ฅผ ๋ฐฐ์๋ณด์",
});
});
ํ์ง๋ง ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํ์ฌ, /product/:num
๊ฒฝ๋ก๋ฅผ ์ง์ ํ๋ฉด, :num
์ ๋์ ์ผ๋ก ๋ณํ๋ ๊ฐ์ด๋ฏ๋ก /product/1
, /product/2
, product/3
...์ด๋ค ๊ฐ์ด ์ค๋ ๋์์ด ๊ฐ๋ฅํ๋ค.
const express = require("express");
const app = express();
app.get("/product/:num", (req, res) => {
res.json({ num: req.params.num });
});
app.listen(3001);
req.params.num
์ URL์์ ์ ๋ฌ๋ num ๊ฐ์ ๊ฐ์ ธ์จ๋ค.- ๋์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ค.
http ๋ชจ๋๋ง์ ์ฌ์ฉํ ๋๋ ๋ผ์ฐํ ์ฒ๋ฆฌ๊ฐ ๊ฝค๋ ๋ณต์กํ๋๋ฐ, express๋ฅผ ์ฌ์ฉํ๋ get(), res.send()๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๋ง์ผ๋ก๋ ๋ฐ๋ก ์ํ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์์๋ค. ์ค๋์ get() ๋ฉ์๋ ์ ๋๋ง ์ฌ์ฉํด์ ์งฑ ์ฝ๋ค ๋๋์ด์๋๋ฐ ๋นจ๋ฆฌ ๋ณต์กํ api ๋ง๋๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์๋ณด๊ณ ์ถ๋ค.