-
제로부터 시작하는 Node.js - 12. RESTful 웹 서비스 개발내가 보기 위해 쓰는 것/Node.js 2019. 11. 16. 17:35
1. RESTful 이 무슨 뜻인가요?
- REST라는 규정을 준수하며 개발된 웹 서비스를 말합니다.
2. REST 규정은 뭔가요?
- (Representational State Transfer)의 약자입니다. 정말 다양한 규정들이 있습니다만 주 목적은 '일관된 웹 서비스 인터페이스 설계' 입니다. 모든 규정을 정리하기는 너무 길고, 저도 전부 알지는 못합니다. 잘 설명된 글이 있어서 링크로 대체하겠습니다. https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html
3. 자세히 안 알려줄거면 왜 이런 챕터를 구성했나요?
- 결국 웹 서비스를 개발한다면 RESTful 이라는 개념, 경험이 반드시 필요합니다. 간단하게라도 짚고 넘어가자는 의미에서 작성하게 되었습니다. 이 글도 완벽한 웹 서비스가 아니라 개념을 훑어보는 수준의 글입니다.
늘 그렇듯, 실전으로 빨리 넘어가면서 훑어보겠습니다.
간단하게 RESTful 서비스 구조를 훑어보겠습니다. 읽어보시면 감이 오시리라 생각합니다.
경로 /collection /collection/:value GET 방식 컬렉션 조회 특정 컬렉션 조회 POST 방식 컬렉션에 새 데이터 추가 없음 PUT 방식 컬렉션 전체를 한꺼번에 변경 컬렉션에 특정 요소 수정 DELETE 방식 컬렉션 전체 삭제 특정 컬렉션 삭제 마치 sql 구문같은 구조네요. 부가적인 예를 들어보겠습니다.
- GET /user - 사용자 전체 조회
- GET /user/123 - 123번 유저 조회
- POST /user - 사용자 추가
- DELETE /user/123 - 123번 유저 정보 삭제
이번 예제는 소스가 많이 깁니다.
우선 전체를 본 후 차근차근 톺아보겠습니다.
index.js 입니다.
const express = require('express') const fs = require('fs') const bodyParser = require('body-parser') let DB = (function () { // 변수 선언 let DB = {} let storage = [] let count = 1 // 메서드 // get < 검색 DB.get = function (id) { if (id) { id = (typeof id == 'string') ? Number(id) : id for (let i in storage) { if (storage[i].id == id) { return storage[i] } } } else { return storage } } DB.insert = function (data) { data.id = count++ storage.push(data) return data } DB.remove = function (id) { id = (typeof id == 'string') ? Number(id) : id for (let i in storage) { if (storage[i].id == id) { storage.splice(i, 1) // 데이터 삭제 성공 이라는 return return true } } // 데이터 삭제 실페 라는 return return false } return DB })() const app = express() app.use(bodyParser.urlencoded({ extended: false })) app.get('/user', function (req, res) { res.send(DB.get()) }) app.get('/user/:value', function (req, res) { res.send(DB.get(req.params.id)) }) app.post('/user', function (req, res) { const name = req.body.name const region = req.body.region if (name && region) { res.send(DB.insert({ name: name, region: region })) } else { throw new Error('error') } }) app.put('/user', function (req, res) { const id = req.params.id const name = req.body.name const region = req.body.region let item = DB.get(id) item.name = name || item.name item.region = region || item.region res.send(item) }) app.delete('/user', function (req, res) { res.send(DB.remove(req.params.id)) }) app.listen(52273, function () { console.log('server is running') })
그리고 간단하게 테스트해보기 위해서 크롬 확장앱 Postman을 사용하겠습니다.
위 소스를 실행한 후
파란색 Postman 확장앱을 클릭합니다.
이런식으로 url을 입력하고 간단하게 요청을 할 수 있는 확장앱 입니다.
위 이미지처럼 입력하고 send를 누르면 POST방식으로 요청이 갔을테니 데이터베이스에 정보가 추가되었을 겁니다.
http:127.0.0.1:52273/user 에 접속하면 데이터가 나와야 합니다.
마찬가지로 PUT, DELETE등의 요청으로 바꿔서 전송하면 수정되거나 삭제할 수 있겠죠.
기능이 잘 작동하는 것을 확인했으면, 소스로 다시 돌아옵시다.
let DB = (function () { // 변수 선언 let DB = {} let storage = [] let count = 1 // 메서드 // get < 검색 DB.get = function (id) { if (id) { id = (typeof id == 'string') ? Number(id) : id for (let i in storage) { if (storage[i].id == id) { return storage[i] } } } else { return storage } } DB.insert = function (data) { data.id = count++ storage.push(data) return data } DB.remove = function (id) { id = (typeof id == 'string') ? Number(id) : id for (let i in storage) { if (storage[i].id == id) { storage.splice(i, 1) // 데이터 삭제 성공 이라는 return return true } } // 데이터 삭제 실페 라는 return return false } return DB })()
이 부분부터 살펴봅시다.
DB라는 객체에 여러 메서드 멤버를 추가하고, 반환하여 저장했습니다.
하나하나의 메서드를 살펴보면 사실 간단한 내용입니다.
// 메서드 // get < 검색 DB.get = function (id) { if (id) { id = (typeof id == 'string') ? Number(id) : id for (let i in storage) { if (storage[i].id == id) { return storage[i] } } } else { return storage } }
매개변수로 받은 값을 삼항연산자를 이용하여 가공하고, storage 배열에 저장된 값에 비교 검색하여 return 하거나, 없을경우 전체를 return 하는, 말 그대로 검색 메서드입니다. 나머지도 위에서 설명한 표처럼 기능하는 매서드들입니다.
DB.insert = function (data) { data.id = count++ storage.push(data) return data }
받은 값을 배열에 추가하는 데이터 저장 메서드입니다.
DB.remove = function (id) { id = (typeof id == 'string') ? Number(id) : id for (let i in storage) { if (storage[i].id == id) { storage.splice(i, 1) // 데이터 삭제 성공 이라는 return return true } } // 데이터 삭제 실페 라는 return return false }
값을 가공하고, 비교하여 맞는 값이 나오면 배열에서 삭제하고 삭제성공 여부를 return 하는 메서드입니다.
이렇게 DB라는 객체를 app.get, post, put 등 여러가지 메서드로 연결시켜놓았죠.
app.get('/user', function (req, res) { res.send(DB.get()) })
/user 라는 로케이션으로 get 요청을 받을경우, 그냥 DB.get을 실행합니다. 매개변수가 없으니 모든 데이터를 보여 줄 것입니다.
app.get('/user/:value', function (req, res) { res.send(DB.get(req.params.id)) })
/user/값 로케이션으로 get 요청을 받으면, 매개변수로 값을 보내줍니다. 검색문에 걸려서 해당 데이터를 보여 줄 것입니다.
app.post('/user', function (req, res) { const name = req.body.name const region = req.body.region if (name && region) { res.send(DB.insert({ name: name, region: region })) } else { throw new Error('error') } })
/user 로케이션으로 post 요청이 올 경우, post요청으로 받은 값이 유효한지 검증하고, DB.insert() 메서드로 보내줍니다. 데이터가 추가 될 것입니다. 값이 유효하지 않을경우 에러처리가 되었습니다.
app.put('/user', function (req, res) { const id = req.params.id const name = req.body.name const region = req.body.region let item = DB.get(id) item.name = name || item.name item.region = region || item.region res.send(item) })
/user 로케이션으로 put 요청을 받은 경우 item 이라는 변수에 검색된 값을 저장하고, 가공하여 보여줍니다.
app.delete('/user', function (req, res) { res.send(DB.remove(req.params.id)) })
DB.remove 메서드에 매개변수로 보내어 삭제될 것입니다.
이렇게 소스는 길지만 체계적인 구조입니다.
전체 내용보다 RESTful 개발이 어떤 느낌인지 감을 잡는게 중요합니다. express 프레임워크까지 간 후엔 반드시 해봐야 할 경험이니까요.
다음 글은 진짜 데이터베이스인 MySQL을 이용하는 방법에 대해서 쓰겠습니다. 그전에 MySQL에 대한 포스팅도 하겠습니다.
'내가 보기 위해 쓰는 것 > Node.js' 카테고리의 다른 글
제로부터 시작하는 Node.js - 14. express 프레임워크 1 - 살펴보기 (0) 2019.12.17 제로부터 시작하는 Node.js - 13. MySQL 연결, CRUD 구현 (0) 2019.11.19 제로부터 시작하는 Node.js - 11. Express 모듈 - 3 (미들웨어 2) (0) 2019.11.16 제로부터 시작하는 Node.js - 10. Express 모듈 - 2 (미들웨어 1) (0) 2019.11.07 제로부터 시작하는 Node.js - 9. Express 모듈 - 1 (0) 2019.11.06