Seongwon Lim

[MongoDB] Node.js mongoose를 이용한 스키마와 모델 구성 및 API 예제 본문

MongoDB

[MongoDB] Node.js mongoose를 이용한 스키마와 모델 구성 및 API 예제

limsw 2022. 5. 9. 20:48
반응형

서론

몽고디비는 비정형 데이터베이스의 특징을 가지고 있다. 따라서 Collection에 들어갈 수 있는 데이터는 어떠한 것도 올 수 있다는 장점이 있지만 데이터 조회 시 조건을 명시하기가 어렵다는 단점도 있다.

이러한 단점을 보완하고자 mongoose모듈은 스키마(Schema) 라는 인터페이스를 제공하고 있다. 스키마를 이용하면 컬렉션의 Document에 어떤 형태의 데이터가 들어가는지 쉽게 정의할 수 있다. 또한 MongoDB는 스키마가 JSON 형태로 작성되는 특징을 가지고 있다.

 

모델(Model)은 스키마를 감싸주는 역할로 스키마에서 정의된 형태를 실제 데이터베이스에 적용이 가능하도록 바뀐 형태를 뜻한다.

 

스키마와 모델의 개념 이해를 돕기 위해 예제로 살펴보고자 한다.

스키마(Schema) 정의하기

필자는 유저 정보를 담을 스키마를 정의하기 위해 루트 디렉토리에 user.js라는 파일을 생성했고 다음과 같이 코드를 구성했다.

const mongoose = require('mongoose');

const userSchema = mongoose.Schema({
    name: {
        type: String,
        maxlength: 50,
    },
    password: {
        type: String,
        minlength: 7,
    },
    sex: {
	    type: String,
    }
});
module.exports = mongoose.model('User', userSchema);

name, password 속성은 타입이 스트링이며 최대 길이 혹은 최소 길이를 정의했다.
sex의 경우에는 별다른 조건 없이 타입만 명시했다.

이렇게 mongoose에서 제공하는 스키마를 통해 스키마를 작성할 수 있으며 module.exports = ...부분은 만들어진 스키마를 User라는 이름의 모델로 외부에서 사용할 수 있도록 해주는 것이다.


쉽게 생각하면 User라는 이름의 모델이 생성된 것이다.

생성한 모델(Model) 사용하기

생성한 모델에 Collection을 추가하는 경우는 인스턴스를 생성해야 한다는 것을 기억하자. 생성한 인스턴스를 통해서 데이터베이스에 Create 작업을 수행할 수 있다.

먼저 라우팅을 통해 효율적으로 파일은 관리하기 위해서 루트 디렉토리에 router.js 라는 파일을 만들었다.


원래는 routes라는 폴더를 만들고 그 안에 users.js 등과 같이 해당 라우터의 기능을 잘 나타내도록 파일을 구성하려고 했으나 이번 포스팅 글에서는 간단하게 구현 방법과 작동 원리만 살펴보고자 하기 때문에 이와 같이 구성했다.

router.js 파일 생성하기

router.js 코드는 다음과 같다.

const express = require('express');
const router = express.Router();

const User = require('./user');


// 모든 Document 조회하기
router.get('', (req, res, next) => {
    
    // 인스턴스 생성 없이 바로 조회 가능
    User.find().then((result) => {
        res.json(result);
    }).catch((err) => {
        res.send(err);
    });
});

// 유저 생성하기
router.post('', (req, res, next) => {
    const user = new User(); // 인스턴스 생성

    user.name = req.body.name;
    user.password = req.body.password;
    user.sex = req.body.sex;
  
   // 또는 인스턴스 생성과 동시에 Document를 정의할 수 있다.
     /*  
     const user = new User({
          name: req.body.name,
          password: req.body.password,
          sex: req.body.sex
      });
      */

    user.save((err) => {
        if(err) {
            return res.status(400).send(err);
        }
        else {
            return res.status(201).send({
                success: true,
            })
        }
        
    });
});

module.exports = router;

router.get() 부분은 모든 Document를 조회하는 메서드이다. MongoDB에서는 find(), findOne(), findById와 같은 다양한 조회 메서드가 존재하지만 지금은 예제이므로 모든 값을 조회할 수 있는 find()를 사용했다.

router.post() 부분은 생성된 모델에 실제 Collection을 추가하는 것이다. 데이터를 저장할 때 메서드는 save()를 이용하며,
Request Body로 3개의 값을 받아서 POST 요청을 보내면 우리가 정의한 모델인 User 모델에 Collection을 추가할 수 있다.

 

요청 경로는 모두 localhost:3000/user로 동일하며 결과는 아래에서 다룰 예정이다.


또한 모델에 Collection을 추가하기 위해서는 인스턴스를 생성해야 하므로 router.post(...)의 경우 필자는 const user = new User();코드를 이용해서 user 라는 이름을 가진 인스턴스를 생성하여 사용했다.

app.js 파일 수정하기

그리고 app.js 파일에서 라우터를 사용하기 위해 아래와 같이 수정한다.

const express = require('express');
const app = express();

const mongoose = require('mongoose');

const DB_ADDRESS = "mongodb+srv://<username>:<password>@cluster0.ab7ss.mongodb.net/myFirstDatabase?retryWrites=true&w=majority"

const router = require('./router'); // 해당 부분 추가


mongoose.connect(DB_ADDRESS
).then(() => {
    console.log("MongoDB Connect")
}).catch((err) => {
    console.log(err)
});

// 해당 부분 추가
app.use('/user', router);


app.listen(3000, () => {
    console.log("Server is Running!");
});

이렇게 파일을 수정하면 localhost:3000/user 경로로 요청을 할 수 있다.

결과 확인하기

먼저 현재 데이터베이스가 비어있는 상태이므로 POST요청을 통해서 Collection을 추가해보았다.

포스트맨을 이용하여 위와 같이 body를 구성 후 요청을 보내면 데이터가 잘 저장되는 것을 확인할 수 있다.

이제 저장된 데이터를 조회하기 위해 GET 요청을 보냈다.

요청한 대로 Collection이 잘 조회된 것을 확인할 수 있다.

MongoDB Atlas에서 확인하기


Deployment의 Databases로 들어간 뒤 위 사진에 나와있는 Browse Collections탭을 클릭하면 생성한 모델과 안에 들어있는 Collection을 확인할 수 있다.


출처

 
Comments