일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- object
- 출처 : https://webdir.tistory.com/506
- 게시판
- http://jeonghwan-kim.github.io/dev/2019/06/25/react-ts.html
- toString
- https://velog.io/@velopert/create-typescript-react-component
- 출처 : https://joshua1988.github.io/web-development/javascript/promise-for-beginners/
- Today
- Total
Back Ground
Node - Rest API [http모듈 웹 서버] 본문
Rest Api와 라우팅
REST API는 REpresentational State Transfer의 약어이다.
네트워크 구조의 한 형식이다.
서버의 자원을 정의하고, 자원에 대한 주소를 지정하는 방법을 가르킨다.
주소는 의미를 명확히 전달하기 위해 명사로 구성된다.
/user이면 사용자 정보에 관련된 자원을 요청하는 것이고,
/post라면 게시글에 관련된 자원을 요청하는 것이라고 추측할 수 있다.
REST API는 주소 외에도 HTTP요청 메서드라는 것을 사용한다.
폼 데이터를 전송할 때 GET 또는 POST 메서드를 지정해보았나?
여기서 GET과 POST가 바로 요청 메서드이다. 거기에 PUT,PATCH, DELETE까지 총 다섯 개가 메서드로 많이 사용된다 .
- GET : 서버 자원을 가져오고자 할 때 사용한다.
요청의 본문(body)에 데이터를 넣지 않는다.
데이터를 서버로 보내야 한다면 쿼리스트링을 사용한다. - POST : 서버에 자원을 새로 등록하고자 할 때 사용한다.
요청의 본문에 새로 등록할 데이터를 넣어 보낸다. - PUT : 서버의 자원을 일부만 수정하고자 할 때 사용한다.
요청의 본문에 치환할 데이터를 넣어 보낸다. - PATCH : 서버 자원의 일부만 수정하고자 할 때 사용한다.
요청의 본문에 일부 수정할 데이터를 넣어 보낸다. - DELETE : 서버의 자원을 삭제하고자 할 때 사용한다.
주소 하나가 요청 메서드를 여러 개 가질 수 있다.
GET 메서드의 /user 주소로 요청을 보내면 사용자 정보를 가져오는 요청이라는 것을 알 수 있고,
POST 메서드의 /user 주소로 요청을 보내면 새로운 사용자를 등록하려 한다는 것을 알 수 있다.
이렇게 주소와 메서드만 보고 요청의 내용을 명확하게 알아 볼 수 있다는 것이 장점이다.
또한, GET 메서드 같은 경우에는 브라우저에서 캐싱할 수도 있어서
같은 주소의 GET 요청을 할 때 서버에서 가져오는 것이 아니라 캐시에 가져올 수도 있다.
이렇게 캐싱이 되면 성능이 좋아진다.
REST API
그리고 HTTP 프로토콜을 사용하면 클라이언트가 누구든 상관없이 서버와 소통할 수 있다.
iOS, 안드로이드, 웹이 모두 같은 주소로 요청을 보낼 수 있다.
즉, 서버와 클라이언트가 분리 되어 있다는 뜻이다.
이렇게 서버와 클라이언트를 분리하면 추후에 서버를 확장할 때 클라이언트에 구애 되지않아 좋다.
HTTP 메서드 | 주소 | 역할 |
GET | / | restFront.html 파일 제공 |
GET | /about | about.html 파일 제공 |
GET | /users | 사용자 목록 제공 |
GET | 기타 | 기타 정적 파일 제공 |
POST | /users | 사용자 등록 |
PUT | /users/사용자id | 해당 id의 사용자 수정 |
DELETE | /users/사용자id | 해당 id의 사용자 제거 |
restServer.css, restServer.html, about.html 파일을 만든 후 다음과 같이 작성한다.
Front는 핵심 내용이 아니기에 간단한 코드 설명만 하고 복붙해서 쓰면 될 것 같다.
restFront.css
1 2 3 4 | a { color: blue; text-decoration: none; } | cs |
restFront.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <!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> <form id="form"> <input type="text" id="username"> <button type="submit">등록</button> </form> </div> <div id="list"></div> <script src="./restFront.js"></script> </body> </html> | cs |
restFront.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | function getUser(){ var xhr = new XMLHttpRequest(); //ajax javascript class // https://developer.mozilla.org/ko/docs/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 = ''; }); | cs |
XMLHttpRequest는 순수 자바스크립트에서 Ajax같이 처리 할 수 있게 해주는 역할을 한다.
서버와 상호작용하기 위해 |
출처 : https://developer.mozilla.org/ko/docs/XMLHttpRequest
restFront.js 스크립트 부분만 설명하자면
페이지가 로딩되면 GET / users로 사용자 목록을 가져온다 (getUser 함수).
수정 버튼과 삭제버튼에 각각 PUT / user/사용자id와 DELETE /users/사용자id로 요청을 보내도록 지정했다.
form을 제출할 때는 POST / users로 데이터와 함께 요청을 보낸다.
restFront.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>RESTful SERVER</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="./restServer.css"/> </head> <body> <nav> <a href="/">HOME</a> <a href="/about">About</a> </nav> <div> <h2>소개 페이지입니다.</h2> <p>사용자 이름을 등록하세요!</p> </div> </body> </html> | cs |
about.html은 노드로 여러 HTML 페이지를 제공하는 것을 보여주기 위해서 추가한 간단한 HTML파일이다.
restServer.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | const http = require('http'); const fs = require('fs'); const users = {}; http.createServer((req,res)=>{ if(req.method === 'GET'){ // GET if(req.url === '/'){ return fs.readFile('./restFront.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'){ //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 = +new Date(); users[id] = name; res.writeHead(201); res.end('등록 성공'); }); } }else if(req.method === 'PUT'){ //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'){ //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번 포트에서 서버 대기 중입니다'); }); | cs |
요청이 어떤 메서드를 사용했는지 req.method로 알 수 있다.
따라서 req.method를 기준으로 if문을 분기 처리하였다.
GET
GET 메서드에서 /, /about 요청 주소는 페이지를 요청하는 것이므로 HTML 파일을 읽어서 전송한다. AJAX요청을 처리하는 /users에서는 users 데이터를 전송한다. JSON형식으로 보내기 위해 JSON.stringify를 해주었다. 그 외의 GET요청은 CSS나 JS파일을 요청하는 것이므로 찾아서 보내주고, 없다면 404 NOT FOUND에러를 응답한다.
|
POST / PUT
POST와 PUT 메서드는 클라이언트로부터 데이터를 받으므로 특별한 처리가 필요하다. req.on('data', 콜백) 과 req.on('end', 콜백 ) 부분인데요. 버퍼와 스트림에 배웠던 readStream이다. readStream으로 요청과 같이 들어오는 요청 본문을 받을 수 있다. 단 문자열이므로 JSON으로 만드는 JSON.parse 과정이 한 번 필요하다. |
DELETE
DELETE 메서드로 요청이 오면 주소에 들어 있는 키에 해당하는 사용자를 제거한다. |
404
해당하는 주소가 없을 경우 404 NOT FOUND 에러를 응답한다. |
'Javascript > Node.js' 카테고리의 다른 글
Node - npm 커맨드 (+npx) (0) | 2019.02.25 |
---|---|
Node - Express-generator 빠르게 설치 [ express 구조 ] (0) | 2019.02.25 |
Node - 쿠키와 세션 [http모듈 웹 서버] (2) | 2019.02.23 |
Node - 요청과 응답 [http모듈 웹 서버] (0) | 2019.02.23 |
Node - Node 기능 (0) | 2019.02.15 |