๐ Bare minimum requirements
ํด๋ผ์ด์ธํธ์ ์ก์ (๋ฒํผ ํด๋ฆญ)์ ๋ฐ๋ผ ๊ฐ๊ธฐ ๋ค๋ฅธ HTTP ์์ฒญ์ ์๋ฒ๋ก ๋ณด๋ด๊ณ , HTTP ์์ฒญ์ ๋ด์ ๋ณด๋ธ ๋จ์ด๋ฅผ ์๋ฌธ์ ๋๋ ๋๋ฌธ์๋ก ์๋ต์ ๋ฐ์ ํ๋ฉด์ ๋ณด์ฌ ์ค๋๋ค.
๐ก ์กฐ๊ฑด
Endpoint(URL) | Method | ๊ธฐ๋ฅ |
/lower | POST | ๋ฌธ์์ด์ ์๋ฌธ์๋ก ๋ง๋ค์ด ์๋ตํด์ผ ํฉ๋๋ค |
/upper | POST | ๋ฌธ์์ด์ ๋๋ฌธ์๋ก ๋ง๋ค์ด ์๋ตํด์ผ ํฉ๋๋ค |
- POST์ ๋ฌธ์์ด์ ๋ด์ ์์ฒญ์ ๋ณด๋ผ ๋๋ HTTP ๋ฉ์์ง์ body(payload)๋ฅผ ์ด์ฉํฉ๋๋ค.
- ์๋ฒ๋ ์์ฒญ์ ๋ฐ๋ฅธ ์ ์ ํ ์๋ต์ ํด๋ผ์ด์ธํธ๋ก ๋ณด๋ด์ผ ํฉ๋๋ค.
- CORS ๊ด๋ จ ํค๋๋ฅผ OPTIONS ์๋ต์ ์ ์ฉํด์ผ ํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ์ preflight request์ ๋ํ ์๋ต์ ๋๋ ค์ค์ผ ํฉ๋๋ค.
- preflight request์ ๋ํ ์๋ต ํค๋๋ ์ด๋ฏธ ์์ฑ๋์ด ์์ต๋๋ค.
๐ ์๋ฒ ์คํ
ํด๋น ๋๋ ํ ๋ฆฌ๋ก ์ง์ ํ ๋ค์, ์๋ ์ปค๋งจ๋๋ฅผ CLI์ ์ ๋ ฅํ๊ณ , ์๋ฒ๋ฅผ ์ข ๋ฃํ๋ ค๋ฉด Ctrl+C๋ฅผ ๋๋ฌ ํ๋ก๊ทธ๋จ์ ๊ฐ์ ์ข ๋ฃ
node server/basic-server.js
์๋ฒ ์ฝ๋๋ฅผ ์์ ํ๊ณ ์ ์ฅํ๋ค๋ฉด ํ๋ก๊ทธ๋จ์ ๋งค๋ฒ ๋ค์ ์คํํด์ผ ํ์ง๋ง, nodemon์ ์ด์ฉํ๋ฉด ์๋ฒ๋ฅผ ๋งค๋ฒ ์คํ์ํฌ ํ์๊ฐ ์์ด npm start๋ง ์ ๋ ฅํด๋ ๋จ
// 1. nodemon ์ค์น
npm install nodemon
// 2. package.json์ "scripts"์ ์๋ ์ฝ๋๋ฅผ ์ถ๊ฐ
"start": "nodemon server/basic-server.js"
// 3. ์ดํ ์๋ฒ ์คํ ์ npm start๋ง ์
๋ ฅํ๋ฉด ๋๋ค.
๐ก ํด๋ผ์ด์ธํธ ์คํ
Client/index.html ์ ์น ๋ธ๋ผ์ฐ์ ์์ ์คํํ๊ฑฐ๋, ํน์ ํฌํธ๋ก ์คํํ๊ณ ์ถ๋ค๋ฉด serve ์ด์ฉ
npx serve -l ํฌํธ๋ฒํธ client/
โ๐ป ๋ด ์ฝ๋ 1 : ์์ฒญ body์์ ๋ฌธ์์ด ์ ์ธ
const http = require('http');
const PORT = 4999;
const ip = 'localhost';
const server = http.createServer((request, response) => {
// CORS ๊ด๋ จ ํค๋๋ฅผ OPTIONS ์๋ต์ ์ ์ฉ
// Method๊ฐ OPTIONS์ธ์ง ๋ถ๊ธฐ
if (request.method === 'OPTIONS') {
response.writeHead(200, defaultCorsHeader);
response.end();
}
// Method๊ฐ POST๋ผ๋ฉด url ํ์ธ ํ ์๋ง์ ์์ฒญ์ ๋ณด๋ด์ฃผ๊ธฐ
if (request.method === 'POST') {
// Method๊ฐ POST๊ณ url์ด /lower๋ผ๋ฉด
if(request.url === '/lower') {
// ๋น ๋ฌธ์์ด ์ ์ธ
let data = '';
request.on('data', chunk => {
data = data + chunk;
});
request.on('end', () => {
data = data.toLowerCase();
// ์๋ฌธ์๋ก ๋ ์๋ต์ ๋๋ ค์ฃผ๊ธฐ
response.writeHead(201, defaultCorsHeader);
response.end(data);
});
// Method๊ฐ POST๊ณ url์ด /upper๋ผ๋ฉด
} else if (request.url === '/upper') {
let data = '';
request.on('data', chunk => {
data = data + chunk;
});
request.on('end', () => {
data = data.toUpperCase();
// ๋๋ฌธ์๋ก ๋ ์๋ต์ ๋๋ ค์ฃผ๊ธฐ
response.writeHead(201, defaultCorsHeader);
response.end(data);
});
// ์ ๋ ๊ฐ์ง ๊ฒฝ์ฐ ๋ชจ๋ ์๋๋ผ๋ฉด
} else {
// ์๋ฌ๋ก ์๋ตํ๊ธฐ
response.writeHead(404, defaultCorsHeader);
response.end();
}
}
});
server.listen(PORT, ip, () => {
console.log(`http server listen on ${ip}:${PORT}`);
});
const defaultCorsHeader = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Accept',
'Access-Control-Max-Age': 10
};
โ๐ป ๋ด ์ฝ๋ 2 : ์์ฒญ body์์ ๋ฐฐ์ด ์ ์ธ
const http = require('http');
const PORT = 4999;
const ip = 'localhost';
const server = http.createServer((request, response) => {
// CORS ๊ด๋ จ ํค๋๋ฅผ OPTIONS ์๋ต์ ์ ์ฉ
// Method๊ฐ OPTIONS์ธ์ง ๋ถ๊ธฐ
if (request.method === 'OPTIONS') {
// ํด๋ผ์ด์ธํธ์ preflight request์ ๋ํ ์๋ต
response.writeHead(200, defaultCorsHeader);
response.end();
}
// Method๊ฐ POST๋ผ๋ฉด url ํ์ธ ํ ์๋ง์ ์์ฒญ์ ๋ณด๋ด์ฃผ๊ธฐ
if (request.method === 'POST') {
// PUT request body(payload) ------------------
// ๋น ๋ฐฐ์ด๋ก ์ ์ธ
let body = [];
request
// 'data'์ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๋ฑ๋กํด ๋ฐ์ดํฐ ๋ฐ๊ธฐ
.on('data', (chunk) => {
// body ๋ฐฐ์ด์ chunk๋ฅผ ๋ด๊ธฐ
body.push(chunk);
})
// 'end'์ ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๋ฑ๋กํด ๋ฐ์ดํฐ ๋ฐ๊ธฐ
.on('end', () => {
// 'data' ์ด๋ฒคํธ์์ ๋ฐ์์ํจ ์ฒญํฌ Buffer(๋ฌธ์์ด ๋ฐ์ดํฐ)๋ฅผ ๋ฐฐ์ด์ ์์ง ํ
// end ์ด๋ฒคํธ์์ ์ด์ด ๋ถ์ด๊ณ ๋ฌธ์์ด๋ก ๋ง๋ค๊ธฐ
body = Buffer.concat(body).toString();
response.writeHead(201, defaultCorsHeader);
// Method๊ฐ POST๊ณ url์ด /lower๋ผ๋ฉด
if (request.url === '/lower') {
// ์๋ฌธ์๋ก ๋ ์๋ต์ ๋๋ ค์ฃผ๊ธฐ
response.end(body.toLowerCase());
// Method๊ฐ POST๊ณ url์ด /upper๋ผ๋ฉด
} else if (request.url === '/upper') {
// ๋๋ฌธ์๋ก ๋ ์๋ต์ ๋๋ ค์ฃผ๊ธฐ
response.end(body.toUpperCase());
// ์ ๋ ๊ฐ์ง ๊ฒฝ์ฐ ๋ชจ๋ ์๋๋ผ๋ฉด
} else {
// ์๋ฌ๋ก ์ฒ๋ฆฌํ ๊ฒ
response.writeHead(404, defaultCorsHeader);
response.end();
}
});
}
});
server.listen(PORT, ip, () => {
console.log(`http server listen on ${ip}:${PORT}`);
});
// ์๋ต ํค๋
const defaultCorsHeader = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Accept',
'Access-Control-Max-Age': 10,
};
๐ก ๊ฒฐ๊ณผ ํ๋ฉด
๋๋ฌธ์๋ฅผ ์ ๋ ฅํ๋ฉด ์๋ฌธ์๋ก, ์๋ฌธ์๋ฅผ ์ ๋ ฅํ๋ฉด ๋๋ฌธ์๋ก ๋์์ผ ํ๋ฉฐ, ๊ฐ๋ฐ์ ๋๊ตฌ์์๋ ์๋ฌ ์์ด ์ ๋์์ง๋ฉด ์ฑ๊ณต์ด๋ค.
๐ฉ๐ป๐ป ๋ฐฐ์ด ์
์ฒ์์๋ HTTP ํธ๋์ญ์ ํด๋ถ์ ๋์์๋ ๋๋ก ๋ฐฐ์ด์ ์ ์ธํ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋๋ฐ, ์ด์ ๋ ๋ชจ๋ฅด๊ฒ ์ง๋ง ๋ฉ์๋๋ ์ ๋จ๊ณ ์๋ฌ๊ฐ ๋ ์ ๋ฌธ์์ด์ ์ ์ธํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๋ณ๊ฒฝํด ์๋ํ๋๋ ์ฑ๊ณตํ๋ค.
๋ค ๋๋ด๋๊ณ ์์ธ์ ์์๋๋ฐ, nodemon์ ์ค์นํ๋ฉด ์ฒ์๋ถํฐ ์๋ฒ ์คํ์ ๋ฐ๋ก ์ํด๋ ๋๋ ์ค ์์๋ ๊ฒ์ด๋ค. nodemon์ ์ค์นํ ์ด์ ๋ ์ฝ๋๋ฅผ ์์ ํ ๋๋ง๋ค node server/basic-server.js๋ก ์๋ฒ๋ฅผ ์คํํ์ง ์์๋ ๋๊ณ , ์ฒ์์ npm start๋ง ์ ๋ ฅํด๋ ์ฝ๋ ์์ ๊ณผ ๋์์ ์๋ฒ๋ฅผ ์คํํ ์ ์๋ค๋ ๊ฒ์ด์๋ค.
์ฝ๋๋ ๋ค ์จ๋๊ณ ์๋ฒ ์คํ ๋ฐฉ๋ฒ์ ์ต์ํ์ง ์์ ๋ ๋ ค๋ฒ๋ฆฐ๊ฑด ๋งค์ฐ ์ํ๊น์ ๋ ์ผ... ํ์ง๋ง ๊ฒฐ๊ณผ์ ์ผ๋ก๋ ์ฝ๋ ํ ์ค ํ ์ค ๋ ์์ธํ ๋ฏ์ด๋ณด๊ณ , HTTP ํธ๋์ญ์ ํด๋ถ ๊ฐ์ด๋๋ ๋ ์์ธํ ์ฝ์ด๋ณด๊ณ , ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด์ ์ดํด๊ฐ ์ ๋์๋ค. ์ค๋์ ์ํ์ฐฉ์ค๊ฐ ๊ฒฐ์ฝ ํ๋์ง ์์๋ค.
๐ ์ฐธ๊ณ ์๋ฃ
- ์ฝ๋์คํ ์ด์ธ ์ ์ดํด๋์ค ์๋ฃ
๋๊ธ