Node.js 교과서를 통해 공부한 내용을 바탕으로 포스팅합니다.
1. REST API란?
REST API는 REpresentational State Transfer의 약어로 네트워크 구조의 한 형식입니다.
서버의 자원을 정의하고, 자원에 대한 주소를 지정하는 방법을 가리킵니다.
주소는 의미를 명확히 전달하기 위해 명사로 구성합니다.
- 예시
- /user : 사용자 정보에 관련된 자원 요청
- /post : 게시글에 관련된 자원을 요청
또한 주소 외에도 총 다섯개의 HTTP 요청 메서드 라는 것을 사용합니다.
- GET : 서버 자원을 가져오고자 할 때 사용
- POST : 서버에 자원을 새로 등록하고자 할 때 사용
- PUT : 서버의 자원을 요청에 들어 있는 자원으로 치환할 때 사용
- PATCH : 서버 자원의 일부만 수정하고자 할 때 사용
- DELETE : 서버의 자원을 삭제하고자 할 때 사용
주소 하나가 요청 메서드를 여러 개 가질 수 있다.
- 예시
- GET메서드의 /user : 사용자 정보를 가져오는 요청
- POST메서드의 /user : 새로운 사용자를 등록하려는 요청
GET 메서드 같은 경우에는 같은 주소의 GET요청 시 캐시에서 가져올 수도 있음 캐싱은 성능을 향상시키는데 도움이 됨
2. RESTful한 웹 서버 만들기
1) 서버 주소 구조
HTTP 메서드 | 주소 | 역할 |
GET | / | restfulMain.html 파일 제공 |
GET | /about | about.html (라우트 테스트용 html) |
GET | /users | 사용자 목록 제공 |
POST | /users | 사용자 정보 등록 |
PUT | /users/사용자id | 해당 id의 사용자 수정 |
DELETE | /users/사용자id | 해당 id의 사용자 제거 |
이렇게 틀을 잡고 사용자 정보를 등록, 수정, 삭제할 수 있는 간단한 서버와 프론트단을 만들어 봅니다.
2) 코드
- restMain.css
a {
color : midnightblue;
text-decoration: none;
}
- restMain.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>RESTful SERVER Practice</title>
<link rel="stylesheet" href="./restMain.css" />
</head>
<body>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<div>
<form id="form">
<input type="text" id="username">
<button type="submit">등록</button>
</form>
</div>
<div id="list"></div>
<script src="./usersList.js"></script>
</body>
</html>
form을 활용해서 데이터를 입력받고
입력받은 데이터는 버튼 클릭에 연결된 이벤트로 처리하게 합니다.
메인에서 동작하는 이벤트에 관한 코드는 usersList.js 파일에 구현합니다.
- usersList.js
function getUser() { // 로딩 시 사용자 가져오는 함수
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status === 200) {
var users = JSON.parse(xhr.responseText);
var list = document.getElementById('list');
list.innerHTML = '';
Object.keys(users).map(function (key) {
var userDiv = document.createElement('div');
var span = document.createElement('span');
span.textContent = users[key];
var edit = document.createElement('button');
edit.textContent = '수정';
edit.addEventListener('click', function () { // 수정 버튼 클릭
var name = prompt('바꿀 이름을 입력하세요');
if (!name) {
return alert('이름을 반드시 입력하셔야 합니다');
}
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status === 200) {
console.log(xhr.responseText);
getUser();
} else {
console.error(xhr.responseText);
}
};
xhr.open('PUT', '/users/' + key);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({ name: name }));
});
var remove = document.createElement('button');
remove.textContent = '삭제';
remove.addEventListener('click', function () { // 삭제 버튼 클릭
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status === 200) {
console.log(xhr.responseText);
getUser();
} else {
console.error(xhr.responseText);
}
};
xhr.open('DELETE', '/users/' + key);
xhr.send();
});
userDiv.appendChild(span);
userDiv.appendChild(edit);
userDiv.appendChild(remove);
list.appendChild(userDiv);
});
} else {
console.error(xhr.responseText);
}
};
xhr.open('GET', '/users');
xhr.send();
}
window.onload = getUser; // 로딩 시 getUser 호출
// 폼 제출
document.getElementById('form').addEventListener('submit', function (e) {
e.preventDefault();
var name = e.target.username.value;
if (!name) {
return alert('이름을 입력하세요');
}
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.status === 201) {
console.log(xhr.responseText);
getUser();
} else {
console.error(xhr.responseText);
}
};
xhr.open('POST', '/users');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({ name: name }));
e.target.username.value = '';
});
- getUser() : 입력된 사용자 정보를 가져오게 하는 함수,
데이터를 로드하고 list div 안에 각 데이터의 개수만큼 (이름, 수정버튼, 삭제버튼) 을 포함한 userDiv를 추가하게 됨 - window.onload = getUser : 페이지가 로딩 될 때 호출할 함수를 지정한다.
- document.getElementById('form').addEventListener('submit', function (e) { ..
: 'form'이라는 아이디를 가진 요소에 submit 이벤트가 수행될 때 동작해야할 부분을 작성하게 됩니다.
위의 코드에서는 아이디가 제출됐을 때의 동작이므로
입력된 이름 값을 담아 POST 메서드를 수행하게 합니다.
- about.html
<!-- 페이지 라우트만 보여주기 위해 텍스트만 넣은 예시 -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>RESTful SERVER Practice</title>
<link rel="stylesheet" href="./restMain.css" />
</head>
<body>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
<div>
<h2>소개 페이지입니다.</h2>
<p>사용자 이름을 등록하세요!</p>
</div>
</body>
</html>
- restServer.js
서버코드가 길기만하지 간단합니다.
딱 GET, POST, PUT, DELETE 네가지 메서드에 대한 처리를 담고 있습니다.
req.method로 들어온 요청에 대해 확인하고 각 요청에 해당하는 처리를 하게 합니다.
const http = require('http');
const fs = require('fs');
const users = {};
http.createServer((req, res) => {
if (req.method === 'GET') {
if (req.url === '/') {
return fs.readFile('./restMain.html', (err, data) => {
if (err) {
throw err;
}
res.end(data);
});
} else if (req.url === '/about') {
return fs.readFile('./about.html', (err, data) => {
if (err) {
throw err;
}
res.end(data);
});
} else if (req.url === '/users') {
return res.end(JSON.stringify(users));
}
return fs.readFile(`.${req.url}`, (err, data) => {
if (err) {
res.writeHead(404, 'NOT FOUND');
return res.end('NOT FOUND');
}
return res.end(data);
});
} else if (req.method === 'POST') {
if (req.url === '/users') {
let body = '';
req.on('data', (data) => {
body += data;
});
return req.on('end', () => {
console.log('POST 본문(Body):', body);
const { name } = JSON.parse(body);
const id = Date.now();
users[id] = name;
res.writeHead(201);
res.end('등록 성공');
});
}
} else if (req.method === 'PUT') {
if (req.url.startsWith('/users/')) {
const key = req.url.split('/')[2];
let body = '';
req.on('data', (data) => {
body += data;
});
return req.on('end', () => {
console.log('PUT 본문(Body):', body);
users[key] = JSON.parse(body).name;
return res.end(JSON.stringify(users));
});
}
} else if (req.method === 'DELETE') {
if (req.url.startsWith('/users/')) {
const key = req.url.split('/')[2];
delete users[key];
return res.end(JSON.stringify(users));
}
}
res.writeHead(404, 'NOT FOUND');
return res.end('NOT FOUND');
})
.listen(8085, () => {
console.log('8085번 포트에서 서버 대기중입니다');
});
3. 결과
이런식으로 웹을 볼 수 있습니다.
위에 이미지는 값을 한번 입력하고 등록한 상태입니다.
여러개 입력하면 여러개의 리스트가 출력됩니다.
수정, 삭제에 대한 이벤트도 반영됩니다.
'Web > Node.js' 카테고리의 다른 글
[Node.js] Express+MongoDB, API 서버 구현하기(1) (0) | 2020.04.01 |
---|---|
[Node.js] Express 구조 이해하기 (0) | 2020.03.15 |
[Node.js] Express 시작하기 (0) | 2020.03.15 |
[Node.js] Node.js란? (0) | 2020.03.12 |