์๋
ํ์ธ์! ์ค๋์ ๋ฐฑ์๋ ๊ธฐ์ ์คํ์ ๋ํ ์ ๋ฐ์ ์ธ ์ดํด๋ฅผ ํด๋ณด๋ ค๊ณ ํฉ๋๋ค.
ํ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์, ๊ทธ๋ฆฌ๊ณ ์์ผ๋ก ์ด๋ค ์ฌ์ด๋ ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ ๋ฐฑ์๋๋ ๊ฒฐ๊ตญ ์ฌ์ฉ๋ ์ ๋ฐ์ ์์ต๋๋ค.
๋ฐ๋ผ์ ๋ฐฑ์๋์ ๋ํ ์ ๋ฐ์ ์ธ ์ดํด๋ ๋ถ๊ฐํผํฉ๋๋ค.
๋ฐ๋ผ์ ์ ๋ ๋ฐฑ์๋์ ๋ํด ์ผ์ ์์ค ์ด์์ ์ธ์งํ๊ณ , ์ง์ ํ์ฉํ ์ ์๋ ๋ฅ๋ ฅ์ ์์ผ๋ ค๊ณ ํด์.
https://youtu.be/M8E6vYAIuzQ?si=AAmfg5_vHCYVwPmu
๋ฐฑ์๋์ ํต์ฌ : ์ ์ ์๊ฒ ์ด๋ป๊ฒ ๋ฐ์ดํฐ๋ฅผ ์์ ์ ์ผ๋ก ์ ๋ฌํ ๊ฒ์ธ๊ฐ
๋ฐฑ์๋์ 3์์
1. ์น ์๋ฒ
์ด๊ธฐ ์น ์๋ฒ๋ ํน์ ์ปดํจํฐ์ ์ค์น๋์ด ์ด๋ค ํ์ผ์ ๋ณด์ฌ๋ฌ๋ผ๋ ์์ฒญ์ด ์ค๋ฉด ํด๋น ํ์ผ์ ๊ทธ๋ด๋ก ๋ณด๋ด์คฌ์.
์ฌ์ฉ์์ ์๊ฐ์ ๋ฐ๋ผ ๋ณํ๊ฐ ์๋ ์ ์ (Static) ์น์ธ ๊ฒ.
๋ํ์ ์ผ๋ก nginx, Apache, Microsoft์ IIS, Caddy๊ฐ ์๋ค.
์ด๋ค์ ์ ์ ํ์ผ์ ์ ๊ณต.
2. WAS
์น์ด ๋์คํ๋๋ฉด์ ๋ฐฉ๋ฌธ์ ์, ์ฌ์ฉ์๋ง๋ค ๋ค๋ฅธ ์ ๋ณด, ๋ฐฉ๋ช ๋ก ๋ฑ์ ์ํ๊ธธ ๋ฐ๋.
์์ฒญ์ ๋ฐ๋ผ ์ค์๊ฐ์ผ๋ก HTML ์์ฑ ๋ถ๊ฐ.
๋์ ์ธ(Dynamic) ์น ํ์ด์ง๋ฅผ ์์ฑํ๊ธฐ ์ํด ํ์.
์๋ก์ด HTML์ ์ค์๊ฐ์ผ๋ก ๋ง๋ค์ด๋ด๋ ๊ฒ.
ํน์ ์์ฒญ -> ๋ฏธ๋ฆฌ ์ฝ์๋ ํ๋ก๊ทธ๋จ์ ์คํ -> ๊ฒฐ๊ณผ๋ฌผ์ ์ ์ ์๊ฒ ์ ๋ฌ
์ฆ, ์์ฒญ์ ๋ฐ๋ผ ์ฝ๋(ํ๋ก๊ทธ๋จ)๋ฅผ ์คํํ๋ ์์ง์ด WAS์ ์ํ!
์๋ฒ : ๋จ์ํ ํ์ผ ์ ๋ฌ -> ์๊ฐ&์ฐ์ฐ&๋ก์ง ์ฒ๋ฆฌ (์ง์ ํ ๋ฐฑ์๋์ ์์)\
์น ์๋ฒ : ์ ์ ์ธ ํ์ผ ๋ฐํ, ์น ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ : ์ธ์์ ๋ฐ๋ผ ๋์ ์ธ ํ์ด์ง ๋ฐํ
WAS : ์๋์ฐจ๊ฐ ์ค์ ๋ก ์์ง์ด๊ฒ ํ๋ ์์ง != BE Framework : ์๋์ฐจ๋ฅผ ๋ง๋ค๊ธฐ ์ํ ์ ๊ตํ ์ค๊ณ๋์ ๋ถํ ์ธํธ.
๊ฐ๋ฐ์๊ฐ BE Framework๋ฅผ ์ด์ฉํด ์์ฑํ ์ฝ๋๊ฐ ์ค์ ์๋ฒ์์ ์คํ์์ผ์ฃผ๋ ํ๊ฒฝ ๊ทธ ์์ฒด
WAS ์์ด BE Framework๋ ๋์ ๋ถ๊ฐ๋ฅ.
3. DB
๐ HTTP ํจํท
| HTTP ํจํท์ ์ฐ๋ฆฌ๊ฐ ์ธํฐ๋ท์์ ์น์ฌ์ดํธ๋ฅผ ๋ณด๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ๋ ์ฌ์ฉํ๋ **'๋ฐ์ดํฐ ๋ฐฐ๋ฌ ์์'**๋ผ๊ณ ์ดํดํ๋ฉด ๊ฐ์ฅ ์ฝ์ต๋๋ค. ์๋ฐํ ๋งํ๋ฉด ๋คํธ์ํฌ ๊ณ์ธต์ ๋ฐ๋ผ '๋ฉ์์ง', '์ธ๊ทธ๋จผํธ', 'ํจํท' ๋ฑ์ผ๋ก ์ฉ์ด๊ฐ ๋๋์ง๋ง, ๋ณดํต ์น ๊ฐ๋ฐ ๋งฅ๋ฝ์์ HTTP ํจํท์ด๋ผ๊ณ ํ๋ฉด **HTTP ์์ฒญ(Request)**๊ณผ **์๋ต(Response)**์ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ์๋ฏธํฉ๋๋ค. 1. HTTP ํจํท์ ๊ตฌ์กฐ์ด ๋ฐฐ๋ฌ ์์๋ ํฌ๊ฒ ์ธ ๋ถ๋ถ์ผ๋ก ๋๋์ด ์์ต๋๋ค.โ ์์ ์ค (Start Line)์์์ ๋งจ ์๋ถ๋ถ์ ๋๋ค. ์ด ์์๊ฐ ๋ฌด์์ ํ๋ ค๋ ๊ฑด์ง ์ ์ฒด๋ฅผ ๋ฐํ๋๋ค.
โก ํค๋ (Header)์์์ ๋ถ์ ์์ธ ์ก์ฅ์ ๋๋ค. ๋ณธ๋ฌธ(Body)์ ๋ํ ๋ฉํ ์ ๋ณด๊ฐ ๋ค์ด์์ต๋๋ค.
โข ๋ฐ๋ (Body)์์ ์์ ๋ ์ค์ ๋ด์ฉ๋ฌผ์ ๋๋ค.
2. ํ๋ฐฐ์ ๋น์ ํ ํ๋ฆ
3. ๋์กฐ ๊ฐ๋ : ํจํท(Packet) vs ๋ฉ์์ง(Message)๋คํธ์ํฌ๋ฅผ ๊น๊ฒ ๊ณต๋ถํ๋ค ๋ณด๋ฉด ์ด ์ฉ์ด๋ค์ด ํท๊ฐ๋ฆด ์ ์์ต๋๋ค.
|
๐ ํฌ๋กฌ์์ HTTP ํจํท ํ์ธํ๊ธฐ (์ค์ต)
ํฌ๋กฌ ๊ฐ๋ฐ์ ๋๊ตฌ๋ก **HTTP ํจํท์ ๋ฏผ๋ฏ(?)**์ ์ง์ ํ์ธํ๋ ๋ฐฉ๋ฒ์ ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ์ง๊ธ ๋ฐ๋ก ์ด ์ฐฝ์์ ๋ฐ๋ผ ํด๋ณด์ธ์.
๐ก ํจํท์ ๋ณด๋ฉด ์ ์ ์๋ ๊ฒ๋ค๊ฐ๋ฐ์๋ค์ ์ด ํจํท๋ค์ ๊ด์ฐฐํ๋ฉฐ ์ด๋ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.
โ ๏ธ ์ฃผ์ํ ์ : HTTPS์ ์ํธํ์ฐ๋ฆฌ๊ฐ ํํ ๋ณด๋ ์ฃผ์์ฐฝ์ ์๋ฌผ์ ํ์(HTTPS)๋ ์ด ํจํท์ ์ํธํํ๋ค๋ ๋ป์ ๋๋ค. ์ค๊ฐ์ ๋๊ตฐ๊ฐ ํจํท์ ๊ฐ๋ก์ฑ๋ ๋ด์ฉ์ ์ฝ์ ์ ์๊ฒ ์ข ์ด ์์๋ฅผ ๊ฐ์ฒ ๊ธ๊ณ ๋ก ๋ฐ๊พผ ์ ์ด์ฃ . ํ์ง๋ง ๋ณธ์ธ์ ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ์์๋ ๊ธ๊ณ ๊ฐ ์ด๋ฆฐ ์ํ์ ๋ฐ์ดํฐ๋ฅผ ๋ณผ ์ ์๋ ๊ฒ์ ๋๋ค. |
๐ ๋ํ์ ์ธ ์ํ ์ฝ๋์ ์๋ฏธ?
์ํ ์ฝ๋๋ ์์๋ฆฌ ์ซ์์ ๋ฐ๋ผ ์๋ฏธ๊ฐ ๋ช
ํํ ๋๋ฉ๋๋ค.
|
๐ ์ง์ ํด๋ณด๋ API ํ ์คํธ (Postman & Thunder Client)
๊ฐ๋ฐ์๋ค์ ๋ธ๋ผ์ฐ์ ๊ฐ๋ฐ์ ๋๊ตฌ๋ง์ผ๋ก๋ ํ๊ณ๊ฐ ์์ด, API๋ฅผ ์ง์ ์๊ณ ์๋ต ํจํท์ ๋ถ์ํ๋ ์ ๋ฌธ ๋๊ตฌ๋ฅผ ์ฌ์ฉํฉ๋๋ค.์ถ์ฒ ๋๊ตฌ 1: Postman (ํฌ์คํธ๋งจ)์ ์ธ๊ณ ๊ฐ๋ฐ์๋ค์ด ๊ฐ์ฅ ๋ง์ด ์ฐ๋ ๋๊ตฌ์ ๋๋ค. ๋ณต์กํ ์์ฒญ๋ ์ ์ฅํด๋๊ณ ๊ณ์ ํ ์คํธํ ์ ์์ต๋๋ค.์ถ์ฒ ๋๊ตฌ 2: VS Code - Thunder ClientVS Code๋ฅผ ์ด๋ฏธ ์ฐ๊ณ ๊ณ์ ๋ค๋ฉด, ํ๋ก๊ทธ๋จ ์์์ ๋ฐ๋ก ์คํํ ์ ์๋ 'Thunder Client' ํ์ฅ ํ๋ก๊ทธ๋จ์ ๊ฐ๋ ฅ ์ถ์ฒํฉ๋๋ค. |
![]() |
๐ ์ค์ต: ๊ฐ์ง API ์๋ฒ์ ํจํท ๋ ๋ ค๋ณด๊ธฐ
|
์ง๊ธ ๋ฐ๋ก ํ
์คํธํด ๋ณผ ์ ์๋ **'JSONPlaceholder'**๋ผ๋ ์ฐ์ต์ฉ ์ฌ์ดํธ๊ฐ ์์ต๋๋ค. ์ค์ ์๋ฒ์ฒ๋ผ ์๋ต ํจํท์ ๋ณด๋ด์ฃผ๋ ๊ณณ์
๋๋ค.
|
![]() |
| { "userId": 1, "id": 1, "title": "...", "body": "..." } |
![]() |
๐ก ์์ (?) ๊ฒธ ๋ค์ ๋จ๊ณ๋ฐฉ๊ธ ํ๋ ์ค์ต ์ฃผ์ ๋์ 1์ 999์ฒ๋ผ ์๋ ์ซ์๋ก ๋ฐ๊ฟ์ ๋ณด๋ด๋ณด์ธ์. ์๋ง ์ํ ์ฝ๋๊ฐ 404 Not Found๋ก ๋ฐ๋ ๊ฒ๋๋ค!์ด ๊ณผ์ ์ด ์ต์ํด์ง๋ฉด ์ง์ Node.js๋ก ๋๋ง์ API ์๋ฒ๋ฅผ ๋ง๋ค์ด์ ๋ด ์ปดํจํฐ๋ก ํจํท์ ์ฃผ๊ณ ๋ฐ์ ์ ์๊ฒ ๋ฉ๋๋ค. Node.js๋ก ๊ฐ๋จํ 'Hello World' ์๋ฒ๋ฅผ ๋ง๋๋ ๋ฒ์ ์๋ ค๋๋ฆด๊น์? |
![]() |
๐ JSON?
| **JSON(JavaScript Object Notation)**์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๊ธฐ ์ํด ๋ง๋ **'ํ
์คํธ ํ์์ ๋ฐ์ดํฐ ๊ท๊ฒฉ'**์
๋๋ค. ์ด๋ฆ์ 'JavaScript'๊ฐ ๋ค์ด๊ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ ์ ์ฉ์ด๋ผ๊ณ ์๊ฐํ ์ ์์ง๋ง, ์ฌ์ค์ ํ๋ ๋ชจ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด(Python, Java, Go ๋ฑ)์์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ๋ ์ฌ์ฉํ๋ ์ธ๊ณ ๊ณตํต ์ธ์ด๋ผ๊ณ ๋ณด์๋ฉด ๋ฉ๋๋ค. 1. JSON์ด ์ด๋ป๊ฒ ์๊ฒผ๋์?JSON์ **ํค(Key)**์ **๊ฐ(Value)**์ ์์ผ๋ก ์ด๋ฃจ์ด์ ธ ์์ผ๋ฉฐ, ์ค๊ดํธ { }๋ฅผ ์ฌ์ฉํฉ๋๋ค. |
{
"์ด๋ฆ": "์ ๋ฏธ๋์ด",
"๋์ด": 2,
"์ง์
": "AI ์ด์์คํดํธ",
"๋ณด์ ๊ธฐ์ ": ["๋ฐ์ดํฐ ๋ถ์", "์ฝ๋ ์์ฑ", "๋๋ด"],
"์ํ": {
"์๋์ง": "์ถฉ๋ง",
"๊ธฐ๋ถ": "ํ๋ณต"
}
}
2. ์ JSON์ ์ฐ๋์?โ ์ฝ๊ธฐ ์ฝ์ต๋๋ค์ฌ๋์ด ๋์ผ๋ก ๋ด๋ "์ด ๋ฐ์ดํฐ๊ฐ ๋ฌด์์ ์๋ฏธํ๋์ง" ํ๋์ ์ ์ ์์ต๋๋ค.โก ๊ฐ๋ณ์ต๋๋ค๊ณผ๊ฑฐ์ ์ฐ๋ XML์ด๋ผ๋ ๋ฐฉ์๋ณด๋ค ๊ธ์ ์๊ฐ ํจ์ฌ ์ ์ด์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ ์๋๊ฐ ๋น ๋ฆ ๋๋ค. (๋น์ ํ์๋ฉด, XML์ด ๊ฒฉ์์ ์ฐจ๋ฆฐ '๊ณต๋ฌธ'์ด๋ผ๋ฉด JSON์ ํต์ฌ๋ง ์ ์ '๋ฉ๋ชจ'์ ๋๋ค.)โข ๊ธฐ๊ณ๊ฐ ํด์ํ๊ธฐ ์ข์ต๋๋ค๋๋ถ๋ถ์ ์ธ์ด์ JSON ํ ์คํธ๋ฅผ ํ๋ก๊ทธ๋๋ฐ ๊ฐ์ฒด๋ก ํ ๋ฒ์ ๋ฐ๊ฟ์ฃผ๋ ๊ธฐ๋ฅ์ด ๋ด์ฅ๋์ด ์์ต๋๋ค.3. ์น ๊ฐ๋ฐ์์์ JSON ํ๋ฆ์ฐ๋ฆฌ๊ฐ ์ง๊ธ๊น์ง ์ด์ผ๊ธฐํ๋ ๊ฐ๋ ๋ค์ JSON์ ์ค์ฌ์ผ๋ก ์ฐ๊ฒฐํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๐ก ์์ฝ
|
๐ ํ์ฑ(Parsing) / ์ญ์ง๋ ฌํ(Deserialization)
| JSON ๋ฐ์ดํฐ์์ ์ํ๋ ์ ๋ณด๋ง ์์ ๊ณจ๋ผ๋ด๋ ์์
์ ํ์ฑ(Parsing) ๋๋ **์ญ์ง๋ ฌํ(Deserialization)**๋ผ๊ณ ๋ถ๋ฆ
๋๋ค. ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ์ด ์์
์ด ๋งค์ฐ ์ฝ์ต๋๋ค! ์ด๋ป๊ฒ ํ๋์ง ๋จ๊ณ๋ณ๋ก ๋ณด์ฌ๋๋ฆด๊ฒ์. 1. ๋ง๋ฒ์ ๋๊ตฌ: . (์ ์ฐ์ฐ์)์๋ฐ์คํฌ๋ฆฝํธ ๊ฐ์ฒด๋ก ๋ณํ๋ ๋ฐ์ดํฐ๋ ๋ง์น ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง ์ง๋์ ๊ฐ์ต๋๋ค. ๋ด๊ฐ ์ํ๋ ๊ฒฝ๋ก๋ฅผ .์ผ๋ก ๋ฐ๋ผ๊ฐ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค.์๊น ์ฐ๋ฆฌ๊ฐ ๋ฐ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ค์ ๊ฐ์ ธ์ ๋ณผ๊น์? |
const post = {
"userId": 1,
"id": 1,
"title": "์๋
, ์ธ์์!",
"body": "์ด๊ฒ์ JSON ๋ฐ์ดํฐ์ ๋ด์ฉ์
๋๋ค."
};
// ํน์ ๋ฐ์ดํฐ ๊ณจ๋ผ๋ด๊ธฐ
console.log(post.title); // ๊ฒฐ๊ณผ: "์๋
, ์ธ์์!"
console.log(post.userId); // ๊ฒฐ๊ณผ: 1
2. ๋ฐ์ดํฐ๊ฐ ๋ณต์กํ ๋ (์ค์ฒฉ ๊ตฌ์กฐ)๋ฐ์ดํฐ๊ฐ ์์ ์์ ๋ ์์๊ฐ ์๋ ๊ตฌ์กฐ๋ผ๋ฉด, ์ ์ ๊ณ์ ์ฐ์ด์ ๋ค์ด๊ฐ๋๋ค. |
const user = {
"name": "ํ๊ธธ๋",
"address": {
"city": "์์ธ",
"zipcode": "12345"
}
};
console.log(user.address.city); // ๊ฒฐ๊ณผ: "์์ธ"
3. ๋ฐ์ดํฐ๊ฐ ์ฌ๋ฌ ๊ฐ์ผ ๋ (๋ฐฐ์ด ๊ตฌ์กฐ)๊ฒ์๊ธ ๋ชฉ๋ก์ฒ๋ผ ๋ฐ์ดํฐ๊ฐ ์ฌ๋ฌ ๊ฐ([ ])๋ผ๋ฉด, ๋ช ๋ฒ์งธ ์์์ธ์ง ๋ฒํธ(์ธ๋ฑ์ค)๋ฅผ ์๋ ค์ค์ผ ํฉ๋๋ค. (์ปดํจํฐ๋ ์ซ์๋ฅผ 0๋ถํฐ ์ ๋๋ค!) |
const posts = [
{ "id": 1, "title": "์ฒซ ๋ฒ์งธ ๊ธ" },
{ "id": 2, "title": "๋ ๋ฒ์งธ ๊ธ" }
];
console.log(posts[0].title); // ๊ฒฐ๊ณผ: "์ฒซ ๋ฒ์งธ ๊ธ"
console.log(posts[1].title); // ๊ฒฐ๊ณผ: "๋ ๋ฒ์งธ ๊ธ"
4. ์ค์ ! ๋ธ๋ผ์ฐ์ ์์ ํด๋ณด๊ธฐ (์ฐ์ต)์ง๊ธ ๋ฐ๋ก ์ด ์ฐฝ์์ F12๋ฅผ ๋๋ฌ Console ํญ์ ์๋ ์ฝ๋๋ฅผ ๋ณต์ฌํด์ ๋ถ์ฌ๋ฃ๊ณ ์ํฐ๋ฅผ ์ณ๋ณด์ธ์.๋ถ์ฌ๋ฃ๊ธฐ๊ฐ ๊ธ์ง ๋์ด ์๋ค๋ฉด
|
// 1. API๋ก ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(response => response.json()) // ํ
์คํธ๋ฅผ JSON ๊ฐ์ฒด๋ก ๋ณํ
.then(data => {
// 2. ์ฌ๊ธฐ์ 'title'๋ง ๊ณจ๋ผ๋ด์ ์ถ๋ ฅ!
console.log("๊ณจ๋ผ๋ธ ์ ๋ชฉ:", data.title);
alert("์๋ฒ์์ ๊ฐ์ ธ์จ ์ ๋ชฉ: " + data.title);
});
![]() |
๐ก ์ ๋ฆฌํ์๋ฉด
|
๐ node.js ์ค์ต
| ์ถํํฉ๋๋ค! ์ง์ ์ฝ๋๋ฅผ ์คํํด์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์จ ๊ทธ ์๊ฐ์ด ๊ฐ๋ฐ์๋ก ์ฑ์ฅํ๋ ๊ฐ์ฅ ์ง๋ฆฟํ ์ฒซ๊ฑธ์์ด์์. ์ด์ ๋จ์ ์๋ฒ๊ฐ ์๋๋ผ, ๋ด ์ปดํจํฐ๋ฅผ ์๋ฒ๋ก ๋ง๋ค์ด์(Node.js) ๋ฐ์ดํฐ๋ฅผ ๋ด๋ณด๋ด๊ณ , ๊ทธ ๋ฐ์ดํฐ๋ฅผ **ํ๋ฉด(React)**์ ๋์ฐ๋ ์ ์ฒด ํ๋ฆ(Full-stack)์ ์์ฃผ ์ฝ๊ฒ ๊ฐ์ด๋ํด ๋๋ฆด๊ฒ์. 1. Node.js๋ก ๋ด ์ปดํจํฐ๋ฅผ ์๋ฒ๋ก ๋ง๋ค๊ธฐ๋จผ์ , ๋ด ์ปดํจํฐ ์์ '์ ์(API)'์ ํ ๋ช ๊ณ ์ฉํด ๋ด ์๋ค. express๋ผ๋ ๊ฐ์ฅ ์ ๋ช ํ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ ๊ฑฐ์์.์ค์น ๋ฐ ์ฝ๋ ์์ฑ
|
const express = require('express');
const cors = require('cors'); // ๋ค๋ฅธ ์ฌ์ดํธ(React)์์ ์ ์ ํ์ฉํด์ฃผ๋ ๋๊ตฌ
const app = express();
app.use(cors()); // ๋ณด์ ๋น์ฅ์ ํ์ด์ค๋๋ค (์๊น ๊ฒช์ผ์ CSP ์๋ฌ ๋ฐฉ์ง)
// ์ด๊ฒ์ด ๋ฐ๋ก ๋๋ง์ JSON ๋ฐ์ดํฐ์
๋๋ค!
const myData = {
id: 1,
title: "๋ด ์ปดํจํฐ ์๋ฒ์์ ์จ ๋ฐ์ดํฐ",
content: "Node.js๋ก ๋ง๋ API ์๋ฒ๊ฐ ์ ์๋ํ๊ณ ์๋ค์!"
};
// API ๊ฒฝ๋ก ์ค์ (GET ๋ฐฉ์)
app.get('/api/info', (req, res) => {
res.json(myData); // ๋ฐ์ดํฐ๋ฅผ JSON ํํ๋ก ๋ณด๋ด์ค๋๋ค.
});
app.listen(4000, () => console.log("์๋ฒ๊ฐ 4000๋ฒ ํฌํธ์์ ์ด๋ ธ์ด์!"));
![]() ![]() ![]() |
| ์ํ, ์์ฃผ ํํ๊ฒ ๋ง๋๋ ์๋ฌ์
๋๋ค! ๋นํฉํ์ง ๋ง์ธ์. ์๋ฌ ๋ฉ์์ง์ ํต์ฌ์ ๋ฐ๋ก ์ด ๋ถ๋ถ์
๋๋ค. ์ปดํจํฐ์ express๋ ์ค์นํ์์ง ๋ชจ๋ฅด์ง๋ง, ์ ๊ฐ ์ฝ๋์ ์ถ๊ฐํ๋ **cors**๋ผ๋ ๋ถํ์ ์์ง ์ค์น๋์ง ์์์ Node.js๊ฐ "๋ ์ด๊ฑฐ ๋ญ์ง ๋ชฐ๋ผ!"๋ผ๊ณ ์ธ์น๋ ์ํฉ์ ๋๋ค. ๐ ๏ธ ํด๊ฒฐ ๋ฐฉ๋ฒํฐ๋ฏธ๋(CMD ๋๋ VS Code ํฐ๋ฏธ๋)์์ ์๋ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ์ฌ ๋ถ์กฑํ ๋ถํ์ ์ค์นํด ์ฃผ์ธ์.npm install cors
![]() node server.js
![]() ๐ค ์ ์ด๋ฐ ์ผ์ด ์๊ธฐ๋์? (npm์ ์ญํ )Node.js ๊ฐ๋ฐ์ ํ ๋๋ ๋ด๊ฐ ์ง์ ๋ชจ๋ ์ฝ๋๋ฅผ ์ง์ง ์๊ณ , ๋จ๋ค์ด ๋ง๋ค์ด๋ ์ ์ฉํ ๋๊ตฌ(ํจํค์ง)๋ฅผ ๊ฐ์ ธ๋ค ์๋๋ค. ์ด๋ **npm**์ด๋ผ๋ ๋๊ตฌ๊ฐ ๊ทธ ๋ถํ๋ค์ ๋ค์ด๋ก๋ํด ์ฃผ๋ ์ญํ ์ ํ์ฃ .
๐ก ๊ฟํ: ์๋ฌ ์ฝ๋ ๋ฒ๋์ค์ ๋ค๋ฅธ ์๋ฌ๊ฐ ๋๋๋ผ๋ code: 'MODULE_NOT_FOUND'๋ผ๋ ๋ฌธ๊ตฌ๊ฐ ๋ณด์ด๋ฉด, **"์, ๋ด๊ฐ npm install๋ก ๋ญ ์ค์น ์ ํ๊ตฌ๋!"**๋ผ๊ณ ๋ฐ๋ก ๋์น์ฑ์๋ฉด ๋ฉ๋๋ค.์๋ฒ๊ฐ ์ ์ผ์ก๋์? ์ ์ผ์ก๋ค๋ฉด ๋ธ๋ผ์ฐ์ ์ฃผ์์ฐฝ์ http://localhost:4000/api/info๋ฅผ ์ ๋ ฅํด์ ์ฌ๋ฌ๋ถ์ ์ฒซ API ์๋ต์ ํ์ธํด ๋ณด์ธ์! |
2. React์์ ์ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ ํ๋ฉด์ ๊ทธ๋ฆฌ๊ธฐ์ด์ ์๋(React)์ด ์ ์(Node.js)์๊ฒ ์๋ฆฌ๋ฅผ ์ฃผ๋ฌธํ ์ฐจ๋ก์ ๋๋ค.React ์ฝ๋ ๊ตฌ์กฐ (ํต์ฌ)React์์๋ useEffect๋ผ๋ ๊ธฐ๋ฅ์ ์ฌ์ฉํด "ํ๋ฉด์ด ๋ํ๋์๋ง์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์๋ผ!"๋ผ๊ณ ๋ช ๋ นํฉ๋๋ค. |
import React, { useState, useEffect } from 'react';
function App() {
const [info, setInfo] = useState(null); // ๋ฐ์ดํฐ๋ฅผ ๋ด์ ๋ฐ๊ตฌ๋
useEffect(() => {
// 1. ๋ด ์๋ฒ์ ์ฃผ๋ฌธํ๊ธฐ
fetch('http://localhost:4000/api/info')
.then(res => res.json())
.then(data => setInfo(data)); // 2. ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ๊ตฌ๋์ ๋ฃ๊ธฐ
}, []);
if (!info) return <div>๋ก๋ฉ ์ค...</div>;
return (
<div style={{ padding: '20px', border: '1px solid blue' }}>
<h1>{info.title}</h1>
<p>{info.content}</p>
</div>
);
}
export default App;
https://nodejs.org/ko/download
Node.js — Node.js® ๋ค์ด๋ก๋
Node.js® is a free, open-source, cross-platform JavaScript runtime environment that lets developers create servers, web apps, command line tools and scripts.
nodejs.org
Node.js๋ ๊ตฌ๊ธ ํฌ๋กฌ์ V8 JavaScript ์์ง์ผ๋ก ๋น๋๋ JavaScript ๋ฐํ์ ํ๊ฒฝ์ ๋๋ค.
๋ณธ๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ ํฌ๋กฌ์ด๋ ์ฌํ๋ฆฌ ๊ฐ์ ์น ๋ธ๋ผ์ฐ์ ์์์๋ง ๋์ํ๋ ์ธ์ด์์ต๋๋ค.
ํ์ง๋ง Node.js๋ ์ด ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ธ๋ผ์ฐ์ ๊ฐ ์๋ ์ด์์ฒด์ (Windows, macOS ๋ฑ) ์์์ ์ง์ ์คํํ ์ ์๊ฒ ํด์ฃผ๋ ์คํ ํ๊ฒฝ(Runtime)์ ๋๋ค.
- ์ฉ๋: ์ฃผ๋ก ์๋ฒ ์ฌ์ด๋(Backend) ๊ฐ๋ฐ์ ์ฌ์ฉ๋ฉ๋๋ค. (์: API ์๋ฒ, ์ค์๊ฐ ์ฑํ
, ์คํธ๋ฆฌ๋ฐ ์๋น์ค)
- = ์ด๋ ์๋ฒ ์ฌ์ด๋์์ JavaScript๋ฅผ ์คํํ ์ ์๋ ํ๊ฒฝ์ ์ ๊ณตํฉ๋๋ค.
- ํน์ง: ๋น๋๊ธฐ I/O์ ์ด๋ฒคํธ ๊ธฐ๋ฐ ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์ฒ๋ฆฌ ์๋๊ฐ ๋งค์ฐ ๋น ๋ฅด๊ณ , ํ ๋ฒ์ ๋ง์ ์ฐ๊ฒฐ์ ์ฒ๋ฆฌํ๋ ๋ฐ ๊ฐ์ ์ด ์์ต๋๋ค.
- ๋น๋๊ธฐ I/O :
- ์ด๋ฒคํธ ๊ธฐ๋ฐ ๋ชจ๋ธ :
- ์์ :
- ๋์กฐ ๊ฐ๋ : Python(Django), Java(Spring), Go ๋ฑ์ด ์๋ฒ ๊ฐ๋ฐ ๋ถ์ผ์์ ๊ฒฝ์ํ๊ฑฐ๋ ๋์กฐ๋๋ ๊ฐ๋ ์ ๋๋ค.
Node.js๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ๊ณผ ์ด๋ฒคํธ ๊ธฐ๋ฐ ๋ชจ๋ธ์ ๊ธฐ๋ฐ์ผ๋ก ๋์ํ์ฌ ๋ง์ ์์ฒญ์ ๋์์ ์ฒ๋ฆฌํ๊ณ , ๋์ฉ๋์ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
Node.js๋ ๋จ์ผ ์ค๋ ๋ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋๊ธฐ์ I/O ์์ ์ ์ฒ๋ฆฌํฉ๋๋ค. ์ด๋ ๋ ผ๋ธ๋กํน(non-blocking) ๋ฐฉ์์ผ๋ก ๋์ํ๋ฉฐ, I/O ์์ ์ด ์๋ฃ๋ ๋๊น์ง ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ค๋ฅธ ์์ ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ๋ค์ค ์์ฒญ์ ๋์์ ์ฒ๋ฆฌํ๊ณ , ๋ง์ ํด๋ผ์ด์ธํธ๋ฅผ ๋์์ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฉ์ดํฉ๋๋ค.
| ๐ก๋ ผ๋ธ๋กํน(non-blocking)์ด๋? |
| - "์ ์ด๊ถ" : ์์ (ํจ์)์ ์ฝ๋๋ฅผ ์คํํ ๊ถ๋ฆฌ ๊ฐ์ ๊ฒ. ์ ์ด๊ถ์ ๊ฐ์ง ํจ์๋ ์์ ์ ์ฝ๋๋ฅผ ๋๊น์ง ์คํํ ํ, ์์ ์ ํธ์ถํ ํจ์์๊ฒ ๋๋ ค์ค๋ค. - "๊ฒฐ๊ณผ๊ฐ์ ๊ธฐ๋ค๋ฆฐ๋ค" : A ํจ์์์ B ํจ์๋ฅผ ํธ์ถํ์ ๋, A ํจ์๊ฐ B ํจ์์ ๊ฒฐ๊ณผ๊ฐ์ ๊ธฐ๋ค๋ฆฌ๋๋์ ์ฌ๋ถ๋ฅผ ์๋ฏธํ๋ค. |
| ๋ธ๋กํน๊ณผ ๋ ผ๋ธ๋กํน์ Aํจ์๊ฐ Bํจ์๋ฅผ ํธ์ถํ์ ๋ ์ ์ด๊ถ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. |
Node.js๋ JavaScript ์ธ์ด๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก ํธ์๋์ ๋ฐฑ์๋๋ฅผ ๋์ผํ ์ธ์ด๋ก ๊ฐ๋ฐํ ์ ์์ด ๊ฐ๋ฐ ์์ฐ์ฑ์ ๋์ ๋๋ค. ๋ํ, Node.js๋ ๋ชจ๋ ์ํ๊ณ๊ฐ ํ๋ถํ์ฌ ๋ค์ํ ๋ชจ๋์ ์ฌ์ฉํ์ฌ ๊ฐ๋ฐ ์๋๋ฅผ ํฅ์์ํฌ ์ ์์ต๋๋ค. ์ด๋ฌํ ํน์ง๋ค๋ก ์ธํด Node.js๋ ๋์ ์ฒ๋ฆฌ๋๊ณผ ํ์ฅ์ฑ์ ์ ๊ณตํ๋ ๋์์ ๊ฐ๋ฐ์๋ค์๊ฒ ํธ๋ฆฌํ ๊ฐ๋ฐ ํ๊ฒฝ์ ์ ๊ณตํฉ๋๋ค.
Node.js๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ๋ฟ๋ง ์๋๋ผ ๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ, ์๋ฒ ์ฌ์ด๋ ์คํฌ๋ฆฝํ , API ์๋ฒ ๋ฑ ๋ค์ํ ์์ญ์์ ํ์ฉ๋ฉ๋๋ค. ์ด๋ฌํ ์ด์ ๋ก Node.js๋ ํ๋์ ์ด๊ณ ํจ์จ์ ์ธ ์น ๊ฐ๋ฐ์ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ๋ก ์ธ์ ๋ฐ๊ณ ์์ต๋๋ค.
Node.js๋ฅผ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ์ฌ์ฉํ๊ณ ์๋ ํ์ฌ์ ํ๋ก์ ํธ๋ ๋ง์ด ์์ต๋๋ค. ๋ช ๊ฐ์ง ๋ํ์ ์ธ ์์๋ฅผ ์๋์ ์๊ฐํด๋๋ฆด๊ฒ์.
- Netflix: Netflix๋ Node.js๋ฅผ ์ฌ์ฉํ์ฌ ๋ง์ ๊ท๋ชจ์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ณ ์ด์ํ๊ณ ์์ต๋๋ค. Node.js์ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ ๋ชจ๋ธ๊ณผ ํ์ฅ์ฑ ๋๋ถ์ Netflix๋ ์๋ง์ ๋์ ์ฌ์ฉ์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ , ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ ์๋น์ค๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
- LinkedIn: LinkedIn์ Node.js๋ฅผ ์ฌ์ฉํ์ฌ ์ค์๊ฐ ์ ๋ฐ์ดํธ์ ์ค์๊ฐ ์๋ฆผ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ๊ณ ์์ต๋๋ค. Node.js์ ์ด๋ฒคํธ ๊ธฐ๋ฐ ๋ชจ๋ธ๊ณผ ๋์ ์ฒ๋ฆฌ๋์ ํตํด LinkedIn์ ์ฌ์ฉ์์๊ฒ ์ค์๊ฐ์ผ๋ก ์ ๋ฐ์ดํธ๋ ์ ๋ณด๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
- Uber: Uber๋ Node.js๋ฅผ ์ฌ์ฉํ์ฌ ์ค์๊ฐ ์์น ์ถ์ , ์ฃผ๋ฌธ ์ฒ๋ฆฌ, ์๊ธ ์ฐ์ ๋ฑ์ ์ฒ๋ฆฌํ๋ ์น ๋ฐฑ์๋ ์์คํ ์ ๊ตฌ์ถํ๊ณ ์์ต๋๋ค. Node.js์ ๋น ๋ฅธ ์๋ต ์๋์ ํ์ฅ์ฑ์ ํตํด Uber๋ ์๋ง์ ์ฌ์ฉ์ ์์ฒญ์ ์ ์ํ๊ฒ ์ฒ๋ฆฌํ๊ณ , ์ค์๊ฐ์ผ๋ก ์ด์ก ์๋น์ค๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
Node.js๋ฅผ ์ ํํ ์ด์ ๋ ํ์ฌ๋ง๋ค ๋ค๋ฅผ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก Node.js๋ JavaScript๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ก ํธ์๋์ ๋ฐฑ์๋๋ฅผ ๋์ผํ ์ธ์ด๋ก ๊ฐ๋ฐํ ์ ์์ด ๊ฐ๋ฐ์๋ค์ ์์ฐ์ฑ์ ๋์ ๋๋ค. ๋ํ, ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ๊ณผ ์ด๋ฒคํธ ๊ธฐ๋ฐ ๋ชจ๋ธ์ ํตํด ๋ง์ ์์ฒญ์ ๋์์ ์ฒ๋ฆฌํ๊ณ , ๋์ ์ฒ๋ฆฌ๋๊ณผ ํ์ฅ์ฑ์ ์ ๊ณตํ ์ ์์ต๋๋ค. ์ด๋ฌํ ์ด์ ๋ก ๋ง์ ํ์ฌ๋ค์ด Node.js๋ฅผ ์ ํํ์ฌ ํจ์จ์ ์ธ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ๊ณ ์์ต๋๋ค.
npx create-react-app my-portfolio
cd my-portfolio
npm install tailwindcss postcss autoprefixer











