앞선 아티클에서 작성한 restServer.js를 계속해서 살펴보겠습니다. 작성된 코드 중, PUT과 POST에 대해서 집중적으로 살펴보겠습니다.
[restServer.js]
const http = require('http');
const fs = require('fs').promises;
const path = require('path');
// 유저 데이터 저장용
const users = {};
http.createServer(async (req, res) => {
try {
console.log(req.method, req.url);
if (req.method === 'GET') {
if (req.url === '/') {
const data = await fs.readFile(path.join(__dirname, 'restFront.html'));
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8'});
return res.end(data);
} else if (req.url === '/about') {
const data = await fs.readFile(path.join(__dirname, 'about.html'));
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
return res.end(data);
} else if (req.url === '/users') {
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
return res.end(JSON.stringify(users));
}
// 주소가 /도, /about도 아닐 경우
try {
const data = await fs.readFile(path.join(__dirname, req.url));
return res.end(data);
} catch (err) {
// 주소에 해당하는 라우트 찾기 불가로 404 not found error 발생
}
} else if (req.method === 'POST') {
if (req.url === '/user') {
let body ='';
// 요청의 body를 stream 형식으로 받는다
req.on('data', (data) => {
body += data;
});
// 요청의 body를 다 받은 후 실행됨
return req.on('end', () => {
console.log('POST 본문(Body):', body);
const { name } = JSON.parse(body);
const id = Date.now();
users[id] = name;
res.writeHead(201, { 'Content-Type': 'text/plain; charset=utf-8'});
res.end('등록 성공');
});
}
} else if (req.method === 'PUT') {
if (req.url.startsWith('/user/')) {
const key = req.url.split('/')[2];
let body = '';
req.on('data', (data) => {
body += data;
});
return req.on('end', () => {
console.log('PUT 본문(Body):', body);
user[key] = JSON.parse(body).name;
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8'});
return res.end(JSON.stringify(users));
});
}
} else if (req.method === 'DELETE') {
if (req.url.startsWith('/user/')) {
const key = req.url.split('/')[2];
delete users[key];
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8'} );
return res.end(JSON.stringify(users));
}
}
res.writeHead(404);
return res.end('NOT FOUND');
} catch (err) {
console.error(err);
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8'});
res.end(err.message);
}
})
.listen(8082, () => {
console.log('8082번 포트 대기 중');
});
HTTP 메서드 | 주소 | 역할 |
GET | / | restFront.html 파일 제공 |
GET | /about | about.html 파일 제공 |
GET | /users | 사용자 목록 제공 |
GET | 기타 | 기타 정적 파일 제공 |
POST | /user | 사용자 등록 |
PUT | /user/사용자id | 해당 id의 사용자 수정 |
DELETE | /user/사용자id | 해당 id의 사용자 삭제 |
우선 여기서 별도의 데이터베이스를 구축한 것은 아니기 때문에, DB 대용으로 사용하는 객체 users를 선언했습니다. 간단하게 정리하자면, 메서드 POST /user일 경우에는 사용자를 새롭게 저장하고 있고 PUT /user/아이디일 경우에는 사용자 데이터를 수정하게 됩니다. DELETE /user/아이디일 경우에는 해당 아이디의 사용자를 제거하겠죠?
여기서 POST, PUT 요청 처리 과정에서는 req.on('data')와 req.on('end')를 사용합니다. 이는 req의 바디에 들어있는 데이터를 꺼내기 위해서 사용합니다. req, res도 내부적으로 스트림으로 되어 있습니다. (각각 readStream과 writeStream)그래서 요청, 응답 데이터가 스트림 형식으로 전달됩니다. on에서 보여지듯 이벤트도 연계되죠.
단, 받은 데이터는 문자열이기 때문에 JSON으로 만드는 JSON.parse 과정을 거치게 됩니다.
위와 같이 동작을 테스트해 Network 탭에서의 기록을 확인해 보겠습니다(만일 Method 칼럼이 안보이면, Name 칼럼 우클릭 후 'Method' 클릭). 'johndoe'를 등록할 경우, Network 탭에서 user와 users가 추가되는 것을 확인할 수 있습니다.
자, 여기서 Name 칼럼은 요청 주소를 의미하게 됩니다. 새로운 유저를 등록할 경우 POST /user , GET /users 이 실행됩니다. Status는 HTTP 응답 코드를 의미하고 Protocol은 통신 프로토콜을, Type은 요청의 종류를 의미하게 되는데 xhr은 AJAX를 의미합니다.
테스트 삼아서 johndoe를 '삭제'버튼을 통해서 삭제할 경우에는 DELETE /user/1721050273489가 요청됩니다. 해당 키를 가진 사용자를 제거하게 되고, 등록 / 수정 / 삭제 발생 후에는 GET으로 /users를 요청해 갱신된 사용자 정보를 가져오게 됩니다.
'Programming > Node.js' 카테고리의 다른 글
5. http 모듈로 서버 만들기 (3) - 쿠키와 세션의 이해 [1] (0) | 2024.07.19 |
---|---|
5. http 모듈로 서버 만들기 (2) - REST와 라우팅 [9] : header, body (0) | 2024.07.16 |
5. http 모듈로 서버 만들기 (2) - REST와 라우팅 [7] (0) | 2024.07.09 |
5. http 모듈로 서버 만들기 (2) - REST와 라우팅 [6] (0) | 2024.07.08 |
5. http 모듈로 서버 만들기 (2) - REST와 라우팅 [5] (0) | 2024.07.08 |