Node.js | mongoose로 API 구현하기

bubblegum·2024년 1월 20일

NodeJS

목록 보기
4/14
post-thumbnail

01 mongoose에 대한 이해

mongoose의 개념

mongoose는 MongoDB에 데이터를 쉽게 읽고 쓰게 해주는 JavaScript 라이브러리이다. mongoose는 JavaScript 코드에서 DB Client 역할을 수행하여 데이터베이스에 연결해준다.

mongoose와 같은 도구를 ODM(Object Document Mapper)이라고도 부른다. ODM(Object Document Mapper)이란, JavaScript의 객체(Object)와 MongoDB의 문서(Document) 사이에서 ‘매핑’을 수행하는 도구를 말한다. JavaScript 코드에서 작업하는 객체(Object)를 MongoDB 데이터베이스의 문서(Document)로 쉽게 변환하거나, 반대로 문서를 객체로 변환해주는 작업을 수행한다.

mongoose의 스키마

아래 사진은 관계형 데이터베이스(RDBMS)와 비관계형 데이터베이스(NoSQL)인 MongoDB의 구조적 차이를 보여준다.

MongoDB의 문서(Documents)

MongoDB에서 가지고 있는 각 데이터 하나하나를 문서(Document)라고 한다. 1개 이상의 Key-Value의 쌍으로 이루어져있으며 JSON 형식으로 구성되어있다. 아래는 2개의 쌍으로 이루어진 documents의 예시이다.

{
    "_id": ObjectId("6682192a1c155bd2f27881"),
    "name": "lyw",
}

MongoDB의 컬렉션(Collection)

컬렉션(Collection)은 여러개의 문서(Document)를 보유할 수 있는 MongoDB의 구성요소이다. JSON 형식의 여러가지 문서(Document)를 보유할 수 있다. 컬렉션(Collection)은 고정된 구성요소가 존재하지 않고, 유연하게 구성할 수 있다. 관계형 데이터베이스(RDB)Table과 동일한 역할을 한다.

mongoose의 스키마(Schema)

스키마(Schema)는 컬렉션(Collection)에 들어가는 Document가 어떤 종류의 값(value)을 가질 것인지, 데이터의 구조와 어떤 제약 사항을 가지는지 정의하고 데이터를 모델링한다. 또한 스키마는 어떤 필드가 있어야 하는지, 필드는 어떤 데이터 타입을 가져야 하는지를 정의한다. 아래는 사용자(Users) 정보를 정의한 스키마의 예시이다.

const UsersSchema = new mongoose.Schema({ 
  name: String, // 문자열 타입입니다.
  age: Number, // 숫자 타입입니다.
  favorites: [String], // 문자열 배열 타입입니다.
  createdAt: { type: Date, default: Date.now }, // 날짜 타입입니다.
  someId: mongoose.Schema.Types.ObjectId // ObjectId 타입입니다.

});

mongoose의 대표적인 스키마 type

  • null : null 값과 존재하지 않는 필드
    • ex: null
  • String : 문자열
    • ex: "mongoDB"
  • Number : 숫자
    • ex: 3.14
  • Date : 날짜
    • ex: new Date()
  • Buffer : 파일을 담을 수 있는 버퍼, UTF-8이 아닌 문자열을 저장
    • ex: 0x65
  • Boolean : true or false
    • ex: true
  • ObjectId(Schema.Types.ObjectId) : 객체 ID, 주로 다른 객체를 참조할 때 넣음
    • ex: ObjectId()
  • Array : 배열 형태의 값
    • ex: ["a", "b", "c"]

mongoose의 모델(Model)

모델(Model)은 데이터베이스에 데이터를 저장하고 읽어올 때 사용되는 데이터의 구조입니다. 스키마를 바탕으로 만들어지고, JavaScript의 객체와 MongoDB 간의 상호작용을 하기 위해 사용합니다. MongoDB의 실제 데이터를 다룰 수 있는 메서드를 지니고 있다. 만약, '사용자'의 데이터를 저장하려면, 사용자(Users) 모델을 사용하여 데이터를 생성하고, 데이터베이스에 저장할 수 있다.


02 mogoose를 이용해 DB에 연결하기

  1. schemas 폴더를 생성하고, index.js 파일에 아래와 같이 작성한다.connect 내부에 들어가는 주소는 MongoDB Atlas에서 대여받은 주소로 변경하고 password를 입력한다.

    import mongoose from 'mongoose';
    const connect = () => {
      mongoose
        .connect(
          'mongodb+srv://<id>:<password>@express-mongo.uy7ttg7.mongodb.net/?retryWrites=true&w=majority',
          {
            dbName: 'spa_mall', // spa_mall 데이터베이스명을 사용합니다.
          },
        )
        .catch((err) => console.log(err))
        .then(() => console.log('몽고디비 연결 성공'));
    };
    
    mongoose.connection.on('error', (err) => {
      console.error('몽고디비 연결 에러', err);
    });
    
    export default connect;
  2. app.js 파일에서 /schemas/index.js 파일에서 생성한 connect 함수를 실행한다.

    import connect from './schemas/index.js'; 
     connect();
  3. app.js 파일을 실행하고, 터미널에 아래와 같이 출력되면 MongoDB와 연결이 성공한 것이다.

    3000포트로 서버가 열렸어요!
     몽고디비 연결 성공

03 mongoose를 이용해 REST API 구현하기

  1. 스키마를 정의하고 모델을 생성한다.

    import mongoose from 'mongoose'; //1. mongoose 가져오기
    
    // 2. 상품(goods)에 대한 정보를 나타내는 스키마를 정의하기
    const goodsSchema = new mongoose.Schema({
      goodsId: {
        type: Number, // 상품의 고유 ID를 나타냅니다.
        required: true, // 필수 항목입니다.
        unique: true, // 중복된 값을 허용하지 않습니다.
      },
      name: {
        type: String, // 상품의 이름을 나타냅니다.
        required: true, // 필수 항목입니다.
        unique: true, // 중복된 값을 허용하지 않습니다.
      },
      thumbnailUrl: {
        type: String, // 상품의 썸네일 이미지 URL을 나타냅니다.
      },
      category: {
        type: String, // 상품의 카테고리를 나타냅니다.
      },
      price: {
        type: Number, // 상품의 가격을 나타냅니다.
      },
    });
    
    // 3. 위에서 정의한 스키마를 이용하여 'Goods'라는 이름의 모델을 생성하기
    export default mongoose.model('Goods', goodsSchema);
  2. 상품 생성 API 작성하기
    router파일에 goods.js에서 'Goods'모델을 가져온 다음, api에 상품을 등록한다.

    import express from 'express';
    // 1. mongoose 모델 가져오기 
    import Goods from '../schemas/goods.js';
    
    const router = express.Router();
    
    // 2. 상품 등록하기
    // localhost:3000/api/goods POST
    router.post('/goods', async (req, res) => {
      const { goodsId, name, thumbnailUrl, category, price } = req.body;
    
      const goods = await Goods.find({ goodsId }).exec();
      if (goods.length) {
        return res
          .status(400)
          .json({ success: false, errorMessage: '이미 존재하는 데이터입니다.' });
      }
    
      const createdGoods = await Goods.create({
        goodsId,
        name,
        thumbnailUrl,
        category,
        price,
      });
    
      return res.status(201).json({ goods: createdGoods });
    });
    
    export default router;
  3. Studio 3T에서 MongoDB에 추가된 데이터를 확인한다.

    Studio 3T는 MongoDB의 데이터를 더욱 편리하게 관리할 수 있는 GUI 툴이다. MongoDB에 저장된 데이터를 직접 확인하고 수정할 수 있기 때문에, JavaScript 코드로만 데이터를 확인하고 수정하는 것보다 더욱 효율적으로 작업과 테스트를 할 수 있다.

profile
황세민

0개의 댓글