-
3-4. 노드 POST, PUT, DELETE 요청 보내기 / HTTP status 코드(상태코드)Node.js 2023. 4. 13. 14:46
I. POST, PUT, DELETE 요청 보내기
이전 게시글에서 GET 메서드 요청에 대해서 알아봤다면,
이번 게시글에서는 같은 예제 속의 POST, PUT, DELETE 요청에 대해서 알아보자.
// about.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>RESTful SERVER</title> <link rel="stylesheet" href="./restFront.css" /> </head> <body> <nav> <a href="/">Home</a> <a href="/about">About</a> </nav> <div> <h2>소개 페이지입니다.</h2> <p>사용자 이름을 등록하세요!</p> </div> </body> </html>
// restFront.html <!DOCTYPE html> <html lang="ko"> <head> <meta charset="utf-8" /> <title>RESTful SERVER</title> <link rel="stylesheet" href="./restFront.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="https://unpkg.com/axios/dist/axios.min.js"></script> <script src="./restFront.js"></script> </body> </html>
// restFront.js async function getUser() { // 로딩 시 사용자 가져오는 함수 try { const res = await axios.get('/users'); const users = res.data; const list = document.getElementById('list'); list.innerHTML = ''; // 사용자마다 반복적으로 화면 표시 및 이벤트 연결 Object.keys(users).map(function (key) { const userDiv = document.createElement('div'); const span = document.createElement('span'); span.textContent = users[key]; const edit = document.createElement('button'); edit.textContent = '수정'; edit.addEventListener('click', async () => { // 수정 버튼 클릭 const name = prompt('바꿀 이름을 입력하세요'); if (!name) { return alert('이름을 반드시 입력하셔야 합니다'); } try { await axios.put('/user/' + key, { name }); getUser(); } catch (err) { console.error(err); } }); const remove = document.createElement('button'); remove.textContent = '삭제'; remove.addEventListener('click', async () => { // 삭제 버튼 클릭 try { await axios.delete('/user/' + key); getUser(); } catch (err) { console.error(err); } }); userDiv.appendChild(span); userDiv.appendChild(edit); userDiv.appendChild(remove); list.appendChild(userDiv); console.log(res.data); }); } catch (err) { console.error(err); } } window.onload = getUser; // 화면 로딩 시 getUser 호출 // 폼 제출(submit) 시 실행 document.getElementById('form').addEventListener('submit', async (e) => { e.preventDefault(); const name = e.target.username.value; if (!name) { return alert('이름을 입력하세요'); } try { await axios.post('/user', { name }); getUser(); } catch (err) { console.error(err); } e.target.username.value = ''; });
// restServer.js const http = require('http'); const fs = require('fs').promises; const users = {}; // 데이터 저장용 http.createServer(async (req, res) => { try { if (req.method === 'GET') { if (req.url === '/') { const data = await fs.readFile('./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('./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도 /users도 아니면 try { const data = await fs.readFile(`.${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('ok'); }); } } 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); users[key] = JSON.parse(body).name; res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); return res.end('ok'); }); } } else if (req.method === 'DELETE') { if (req.url.startsWith('/user/')) { const key = req.url.split('/')[2]; delete users[key]; res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' }); return res.end('ok'); } } 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번 포트에서 서버 대기 중입니다'); });
// restFront.css a { color: blue; text-decoration: none; }
✨ restServer.js 에 주목
- POST 와 PUT 메서드는 클라이언트로부터 데이터를 받으므로 특별한 처리가 필요하다.
req.on('data', 콜백) 과 req.on('end', 콜백) 부분인데,
제가 쓴 버퍼와 스트림 게시글(https://junu128.tistory.com/56) 에서 배웠던 readStream 이다.
readStream 으로 요청과 같이 들어오는 요청 본문을 받을 수 있다.
단, 문자열이므로 JSON 으로 만드는 JSON.parse 과정이 한 번 필요하다.
- DELETE 메서드로 요청이 오면 주소에 들어있는 키에 해당하는 사용자를 제거한다.
- 해당하는 주소가 없을 경우, 404 NOT FOUND 에러를 응답한다.
✨ 아래는 각각의 메서드를 실행한 결과이다.
- 이름 작성 후 등록버튼 클릭 시 (PUT)
- "ㄴㅇㄴㅇ" 에 대한 수정 버튼 클릭 시(PATCH)
- "홍겨란"에 대한 삭제 버튼 클릭 시 (DELETE)
II. HTTP 상태(status) 코드 분류
상태 코드의 종류와,
프로그래밍을 하다가 자주 접할 수 있는 코드들 위주로 적어보겠다.
1. 정보 응답 ( 1XX )
2. 성공 응답( 2XX )
- 200 OK : "요청이 성공적으로 되었습니다." 라는 뜻으로, 가장 많이 볼 수 있는 성공 응답 중 하나이다.
- 201 Created : "요청이 성공적이였으며 그 결과로 새로운 리소스가 생성되었습니다." 라는 뜻으로, 주로 POST 요청 또는 일부 PUT 요청 이후에 따라온다.
3. redirection 메세지 ( 3XX )
4. 클라이언트 에러 응답 ( 4XX )
- 400 Bad Request : "잘못된 문법으로 인하여 서버가 요청을 이해할 수 없음" 이라는 뜻이다.
- 401 Unauthorized : "미승인" 이라고 알려져 있지만, 사실 "비인증" 이라는 뜻으로, 서버가 클라이언트가 누군지 모른다는 뜻이다.
- 403 Forbidden : "클라이언트는 콘텐츠에 접근할 권리를 가지고 있지 않습니다." 라는 뜻으로, 접근 권한이 없다는 의미이다. 401과는 다르게, 서버는 클라이언트가 누군지는 알고 있는 상태이지만 해당 클라이언트가 접근 권한이 없으므로 접근을 거절하기 위한 코드이다.
- 404 Not Found : "서버는 요청받은 리소스를 찾을 수 없습니다." 라는 뜻으로, 브라우저에게는 알려지지 않은 URL 을 의미한다.
예를 들어 URL 요청을 "/hello" 로 해야 하는데 "/whatsMatter" 라고 잘못 요청했을 때, 나타나는 에러 코드이다.
- 405 Method Not Allowed : 요청한 메소드는 서버에서 알고 있지만 제거되었고 사용할 수 없습니다" 라는 뜻이다.
5. 서버 에러 응답 ( 5XX )
- 500 Internal Server Error : "서버가 처리 방법을 모르는 상황이 발생했습니다." 라는 뜻이다.
서버가 아직 처리 방법을 모른다는 의미로, 아직 서버가 죽지는 않은 상태이다.
✨ 더 많은 코드에 대해서 알고 싶다면? 아래 링크 참고 !!!!
https://developer.mozilla.org/ko/docs/Web/HTTP/Status
HTTP 상태 코드 - HTTP | MDN
HTTP 응답 상태 코드는 특정 HTTP 요청이 성공적으로 완료되었는지 알려줍니다. 응답은 5개의 그룹으로 나누어집니다: 정보를 제공하는 응답, 성공적인 응답, 리다이렉트, 클라이언트 에러, 그리고
developer.mozilla.org
'Node.js' 카테고리의 다른 글
3-6. 노드 세션(Session) 이해하고 사용하기 (0) 2023.04.14 3-5. 노드 쿠키의 모든 것 (0) 2023.04.13 3-3. 노드 REST API 서버 만들기 (0) 2023.04.13 3-2. 노드 fs로 HTML 파일 읽어서 제공하기 (0) 2023.04.13 3-1. 노드 HTTP 서버와 클라이언트 (0) 2023.04.13