서점 샘플 응용하기 - 01 에 이어서 02 에서는 서버-Node.js & MongoDB- 와 붙이는 작업을 한다. 원문이 과거 버전이어서 좀 더 이해하기 쉽도록 재구성하였고, RESTful API 테스트 방법도 새롭게 시도해 보았다
1) RESTful API 와 Node.js 환경 구성하기
- 호출하는 API 목록
/api/rides GET 모든 라이딩정보의 배열을 얻는다.
/api/rides/:id GET 아이디가 :id인 라이딩정보을 얻는다.
/api/rides POST 새로운 라이딩정보를 추가하고 아이디가 추가된 그 정보를 반환한다.
/api/rides/:id PUT 아이디가 :id인 라이딩정보를 수정한다.
/api/rides/:id DELETE 아이디가 :id인 라이딩정보를 삭제한다.
- node.js & mongodb 설치되어 있음을 가정하고 node.js 모듈을 설치한다
// 모듈 설치
$ npm install express
$ npm install mongoose
- public 디렉토리를 생성하여 img, js, css, index.html 파일을 public 디렉토리 밑으로 옮긴다
- server.js 코딩하기
// 모듈 의존성
var express = require("express"); //웹 프레임워크
// 서버를 생성한다
var app = express();
// 서버를 설정한다
app.configure(function () {
app.use(express.bodyParser()); //요청 바디를 파싱해서 req.body를 만든다
app.use(express.methodOverride()); //HTTP 메쏘드를 덮어쓰기 위해서 req.body를 확인한다
app.use(app.router); //url과 HTTP 메쏘드에 기반한 라우팅을 수행한다
app.use(express.static(__dirname + '/public')); //정적 자원을 제공하는 곳
app.use(express.errorHandler({ dumpExceptions:true, showStack:true })); //개발시점에 모든 에러를 보여준다
});
// 서버를 구동한다
app.listen(8080, function () {
console.log("Express server listening on port %d in %s mode", 8080, app.settings.env);
});
- nodemon 을 통해서 구동하기 : 수정된 코딩이 있으면 자동으로 restart node 수행 (nodemon 블로깅)
$ nodemon server.js
15 Mar 14:37:11 - [nodemon] v0.7.2
15 Mar 14:37:11 - [nodemon] watching: ~/backbone/riding
15 Mar 14:37:11 - [nodemon] starting `node server.js`
Express server listening on port 8080 in development mode
- MongoDB 구동하기
// mongod 데몬 실행
$ mongod --dbpath /mongodb/ride_database/
Fri Mar 15 15:33:19 [initandlisten] MongoDB starting : pid=50361 port=27017 dbpath=/Users/nulpulum/mongodb/ride_database/ 64-bit host=mac-42-retina.local
Fri Mar 15 15:33:19 [initandlisten] db version v2.2.3, pdfile version 4.5
... 중략 ..
Fri Mar 15 15:33:19 [websvr] admin web console waiting for connections on port 28017
Fri Mar 15 15:33:19 [initandlisten] waiting for connections on port 27017
// Node.js 서버가 구동 되어 있으면 연결 정보가 출력된다
Fri Mar 15 15:34:27 [initandlisten] connection accepted from 127.0.0.1:61129 #1 (1 connection now open)
Fri Mar 15 15:34:27 [initandlisten] connection accepted from 127.0.0.1:61130 #2 (2 connections now open)
Fri Mar 15 15:34:27 [initandlisten] connection accepted from 127.0.0.1:61131 #3 (3 connections now open)
Fri Mar 15 15:34:27 [initandlisten] connection accepted from 127.0.0.1:61132 #4 (4 connections now open)
2) Mongoose 통하여 MongoDB 접근하기
- biz.js 파일을 생성하고 mongoose 코딩하기
+ Mongoose 용 schema와 model을 만든다
+ MongoDB 에 접속한다
+ 모듈패턴으로 업무 callback CRUD function 들을 GET, POST, PUT, DELTE 메소드를 정의한다
- server.js 안에 RESTful API 추가하기
.. 중략 ..
// 서버를 설정한다
app.configure(function () {
app.use(express.bodyParser()); //요청 바디를 파싱해서 req.body를 만든다
app.use(express.methodOverride()); //HTTP 메쏘드를 덮어쓰기 위해서 req.body를 확인한다
app.use(app.router); //url과 HTTP 메쏘드에 기반한 라우팅을 수행한다
app.use(express.static(__dirname + '/public')); //정적 자원을 제공하는 곳
app.use(express.errorHandler({ dumpExceptions:true, showStack:true })); //개발시점에 모든 에러를 보여준다
});
// mongoose 업무모듈인 biz.js 가져오기
var biz = require("./biz");
// RESTful API에 대한 호출에 대하여 biz.js 모듈의 callback 펑션을 설정함
app.get( '/api/rides', biz.readAll);
app.post('/api/rides', biz.create);
app.get( '/api/rides/:id', biz.read);
app.put( '/api/rides/:id', biz.update);
app.delete('/api/rides/:id', biz.delete);
// 서버를 구동한다
app.listen(8080, function () {
console.log("Express server listening on port %d in %s mode", 8080, app.settings.env);
});
3) RESTful API 테스트하기
- Chrome extention 인 "Advanced REST client" 설치한다 : Chrome Web Store에서 검색하고 설치하면 됨
- Advanced REST client 실행
+ POST 메소드를 선택 (GET, PUT, DELETE 순으로 실행하여 본다)
+ 하단의 Form 탭을 선택하여 key=value 를 추가한다
+ "Send" 버튼을 클릭하면 결과가 최하단에 나온다 (200 OK)
- MongoDB에서 결과 조회
$ mongo
MongoDB shell version: 2.2.3
connecting to: test
> show dbs
local (empty)
// POST가 성공하면 데이터베이스가 보인다
> show dbs
local (empty)
ride_database 0.203125GB
> use ride_database
switched to db ride_database
> show collections
rides
system.indexes
> db.rides.find().toArray();
[
{
"title" : "투어 드 코리아",
"rider" : "윤복자",
"ridingDate" : ISODate("2013-06-01T00:00:00Z"),
"keywords" : "코리아 싸이클링",
"_id" : ObjectId("5142ccbd1b06d36acc000001"),
"__v" : 0
}
]
>
- PUT 은 URL 뒤에 MongoDB document의 _id 값인 5142ccbd1b06d36acc000001 을 붙여준다. (DELETE 도 동일)
4) Backbone.js 와 Node.js 연결하기
- 클라이언트 <-> 서버 연결
+ MongoDB사용시 : _id 지정하기
+ url 설정 : /api/rides
+ fetch() 호출
+ reset callback으로 render 설정
- ride.js 백본파일을 수정 : 라이딩 정보 목록 가져오기 == 컬렉션 모델에서 url 설정
var Ride = Backbone.Model.extend({
defaults:{
coverImage:"img/my_cycle.png",
title:"2011년 대관령 대회",
rider:"Yun YoungSik",
ridingDate:"2011",
keywords:"대관령 힐크라이밍 대회"
},
idAttribute: "_id" // MongoDB 사용시 바꾸어줌
// idAttribute 와 같은 효과를 같는다
/*parse:function (response) {
console.log(response);
response.id = response._id;
return response;
}*/
});
.. 중략 ..
// rides
/* var rides = [{title:"대관령 힐크라이밍 대회", rider:"Yun YoungSik", ridingDate:"2010", keywords:"대관령"},
{title:"미시령 힐크라이밍 대회", rider:"Yun DoWon", ridingDate:"2011", keywords:"미시령"},
{title:"투어 드 코리아", rider:"Yun YoungSik", ridingDate:"2012", keywords:"코리아"}];*/
var rides = []; // 위의 샘플은 사용하지 않고 빈 배열을 만들어 준다
////////////////////
// Ride Collection
var Rides = Backbone.Collection.extend({
model : Ride,
url : '/api/rides' // 서버 호출 API
});
///////////////////
// Collection View
var RidesView = Backbone.View.extend({
el: $("#rides"),
initialize: function(){
this.collection = new Rides(rides);
// 서버로 부터 데이터 가져오기
this.collection.fetch();
this.render();
// 컬렉션 add가 호출되면 renderRide를 trigger 한다
this.collection.on("add", this.renderRide, this);
this.collection.on("remove", this.removeRide, this);
// fetch()가 비동기적이기 때문에 Backbone이 reset을 호출하면 trigger 될 수 있도록 한다
this.collection.on("reset", this.render, this);
},
- 브라우져 호출 : MongoDB 의 데이터를 가져와서 Backbone이 데이터를 reset 하게 되면 입력한 라이딩정보가 출력된다
- 날짜가 이상하게 나오므로 jQuery를 이용하여 날짜를 포멧팅 해준다
<script id="rideTemplate" type="text/template">
<img src="<%= coverImage %>"/>
<ul>
<li><%= title %></li>
<li><%= rider %></li>
<!-- 년/월/일 만 표현 -->
<li><%= $.format.date(new Date(ridingDate), 'yyyy/MM/dd') %></li>
<li><%= keywords %></li>
</ul>
<button class="delete">Delete</button>
</script>
</div>
<script src="js/jquery.js"></script>
<!-- 다운로드 받아서 js 폴더에 놓는다 -->
<script src="js/jquery-dateformat.js"></script>
<script src="js/underscore.js"></script>
<script src="js/backbone.js"></script>
<script src="js/ride.js"></script>
- 브라우져 화면에서 MongoDB로 add 하기 : Backbone의 ride.js 에서 addRide 수정
var RidesView = Backbone.View.extend({
el: $("#rides"),
initialize: function(){
this.collection = new Rides(rides);
// 서버로 부터 데이터 가져오기
this.collection.fetch();
this.render();
// 컬렉션 add가 호출되면 renderRide를 trigger 한다
this.collection.on("add", this.renderRide, this);
this.collection.on("remove", this.removeRide, this);
// fetch()가 비동기적이기 때문에 Backbone이 reset을 호출하면 trigger 될 수 있도록 한다
this.collection.on("reset", this.render, this);
},
render: function(){
var that = this;
_.each(this.collection.models, function(item){
that.renderRide(item);
}, this);
},
renderRide: function(item){
var rideView = new RideView({
model: item
});
this.$el.append(rideView.render().el);
},
addRide: function(e){
e.preventDefault();
var formData = {};
// jQuery의 each로 formData key=value 객체를 만듦
$("#addRide").children("input").each(function (i, el) {
if ($(el).val() !== "") {
formData[el.id] = $(el).val();
}
});
// rides 배열에 저장
rides.push(formData);
// 컬렉션 객체에 저장
// 서버로 저장하기 기존 add를 create 으로 바꾸면 된다
this.collection.create(formData);
//this.collection.add(new Ride(formData));
},
- 브라우져 결과 화면 : "평택 대회" 입력
- MongoDB의 결과값 : 3개의 도큐먼트가 존재한다
> db.rides.find().toArray();
[
{
"title" : "투어 드 코리아3",
"rider" : "윤영식",
"ridingDate" : ISODate("2012-06-01T00:00:00Z"),
"keywords" : "싸이클링 코리아 우승",
"_id" : ObjectId("5142dc4ae196a916e0000001"),
"__v" : 0
},
{
"title" : "대관령 힐크라이밍 대회",
"rider" : "윤도원",
"ridingDate" : ISODate("2013-07-01T00:00:00Z"),
"keywords" : "강원도 우승목표",
"_id" : ObjectId("5142dd8cba03b734e1000001"),
"__v" : 0
},
{
"title" : "평택 대회",
"rider" : "윤복자",
"ridingDate" : ISODate("2013-03-01T00:00:00Z"),
"keywords" : "고속도로 개통기념",
"_id" : ObjectId("5142de7351b4341ee2000001"),
"__v" : 0
}
]
>
- 원문에 포함된 날짜 포함하기와 키워드배열로 만들기는 패스~~~ ^^;
** 전체 소스 코드
<참조>
- 원문 : Backbone.js Developing 번역글
- Node.js & Express & Mongoose ToDo 예제
- Tool : Advanced Rest Client
'Backbone.js' 카테고리의 다른 글
[Backbone.js] RequireJS를 통한 브라우져상의 모듈화 (0) | 2013.03.16 |
---|---|
[Handlebar.js] Client Side 템플릿 엔진 사용하기 (0) | 2013.03.16 |
[Backbone.js] 서점 샘플 응용하기 - 01 (0) | 2013.03.15 |
[Backbone.js] 큰 규모의 SPA 개발을 위한 준비 (0) | 2013.03.12 |
[Backbone.js] Underscore.js 이해와 API 테스트 (0) | 2013.03.11 |