참고 서적: 풀스택 개발자를 위한 MEAN 스택 입문

개발 환경: Mac OS


책을 읽고 관련한 정보가 잊혀지기 전에 간략하게 작성한다.






1. mongodb 설치


brew install mongodb

mongo --version > v4.0.1


로컬에 디비를 설치하지 않는 경우는 호스팅 사이트를 이용할 수 있다.

내 경우는 책에서 추천한 mlab에서 제공하는 무료 500mb 플랜을 받아 연결했다.

몽고디비 인스턴스 관리 외에 데이터 관리를 위한 GUI도 제공하기 때문에 여러모로 쉘 작업보다 편리하다.




2. mongoose 설치


전역으로 설치하지 않는 경우는 작업 경로로 이동해서 작업해야 하며 전역으로 설치시에는 --save 대신 -global(-g) 옵션이 필요하다.


npm install mongoose --save




3. mongoose 사용


몽구스 사용은 스키마 정의부터 시작된다. 스키마를 정의하고 나면 해당 스키마를 통해 모든 CRUD 작업을 코드에서 통제할 수 있다.

(개인적으로는 java 웹 애플리케이션에서 작성하던 Entity와 유사하게 여겨졌다. 다만 Entity는 단순히 테이블 명세를 객체화 하기 위한 POJO 클래스에 지나지 않아 정보를 담는 것 외에는 특별한 일을 하지 않는다.)

책에서 작성한 HR앱을 베이스로 한 간단한 스키마 예제를 첨부한다.


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
var mongoose = require('mongoose')
var Schema = mongoose.Schema
var EmployeeSchema = new Schema({
    id: {
        type: String,
        required: true,
        unique: true
    },
    name: {
        first: {
            type: String,
            required: true
        },
        last: {
            type: String,
            required: true
        }
    },
    team: {
        type: Schema.Types.ObjectId,
        ref: 'Team'
    },
    image: {
        type: String,
        default'images/user.jpg'
    },
    address: {
        lines: {
            type: [String]
        },
        city: {
            type: String
        },
        zip: {
            type: Number
        }
    }
})
 
module.exports = mongoose.model('Employee', EmployeeSchema)
cs


▲ models/EmployeeSchema.js


코드는 매우 쉽고 직관적이다. 언급하고 넘어갈 만한 부분은 연관성을 나타낸 team에 대한 정보다.

Schema.Types.ObjectId는 team을 위한 값이 몽고디비의 유일한 식별자라는 뜻으로 team을 위해 사용할 모델명은 Team임을 알 수 있다. TeamSchema의 정의는 아래와 같다.


1
2
3
4
5
6
7
8
9
10
var mongoose = require('mongoose')
var Schema = mongoose.Schema
var TeamSchema = new Schema({
    name: {
        type: String,
        required: true
    }
})
 
module.exports = mongoose.model('Team', TeamSchema)
cs


▲ models/TeamSchema.js


모델 정의 때 사용된 값이 ref에서 사용되는 것을 확인할 수 있다. 이제 스키마를 통해 간략한 CRUD 코드를 작성해 보자.


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
var mongoose = require('mongoose')
var Team = mongoose.model('Team')
 
exports.findOne = findOne
exports.insert = insert
exports.update = update
exports.remove = remove
 
function findOne(team, callback) {
    Team.findOne(team, function (err, data) {
        callback(data)
    })
}
 
function insert(team, callback) {
    Team.create(team, function (err, target) {
        callback(null'[inserted]')
    })
}
 
function update(team, changing, callback) {
    team.name = changing
    Team.update(team, function (err, target) {
        callback(null'[updated]')
    })
}
 
function remove(team, callback) {
    Team.remove(team, function (err, target) {
        callback(null'[deleted]')
    })
}
cs


lib/team.js


TeamSchema와 연관된 CRUD 코드를 모아둔 서비스다.

예제 코드이므로 별도의 에러 처리는 모두 생략했으나 실제 서비스에서는 반드시 작성하도록 한다.


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
require('./models/team')
var mongoose = require('mongoose')
var Team = mongoose.model('Team')
var teamService = require('./lib/team')
 
var dbUrl = 'mongodb://{url}:{port}/{db name}'
mongoose.connect(dbUrl, function (err) {
    if (err) {
        return console.log('[DB 연결 실패] ' + err)
    } else {
        console.info('[DB 연결] ' + Date.now())
 
        var data = { name'Development' }
        teamService.insert(data, logger)
        
        // teamService.findOne(data, function (record) {
        //     console.info('[updating...]')
        //     console.info('[before] ' + record.name)
        //     teamService.update(record, 'new Development', logger)
        //     console.info('[after] ' + record.name)
        // })
    }
})
 
function logger(err, act) {
    console.log(act)
}
 
process.on('SIGINT'function () {
    mongoose.connection.close(function () {
        console.info('[DB 연결 해제] ' + Date.now())
        process.exit(0)
    })
})
cs


▲ 서비스 호출 예시


현재 코드에서는 새로운 행을 추가하는 코드만 활성화되어 있다.

수정, 삭제에 관한 코드 호출과 해당 CRUD를 제공하는 RestfulAPI를 작성은 이제까지의 포스팅을 참고해 작성할 수 있다.




몽고디비가 아닌 다른 데이터베이스(관계형을 아우르는)를 연결하고 싶은 경우는 관련한 노드 모듈을 찾아볼 것을 추천한다. 책에서는 별도로 MySQL을 언급하고 있다.



WRITTEN BY
Project JT
2명의 개발자가 팀 프로젝트를하며 사용한 기술들을 남기는 팀 블로그입니다.