[DB] mongoDB 셋팅 & nodejs 백엔드와 연결

thousand_yj·2023년 7월 23일
1

Willing 프로젝트

목록 보기
12/18

MongoDB

무료로 사용 가능한 NoSQL 방식의 데이터베이스. 따로 SQL문을 작성할 필요가 없으며 코드를 사용하여 DB에 접근하고 처리할 수 있다. 진입장벽이 낮다는 장점이 있다!

MongoDB 사용하기

https://www.mongodb.com/ko-kr 사이트에 접속하여 시작하면 된다. 내 컴퓨터에서 직접 DB를 작동시킬 수 있는 서버를 가동해도 되지만 평생 컴퓨터 안 끌 자신이 없으니 서버를 사용하자. 다행히 평생 무료로 DB를 돌릴 수 있는 서버를 제공해주는 옵션이 있다. MongoDB Atlas를 사용하여 Free FOREVER 옵션을 갖는 클러스터를 만들어주자. Shared 옵션으로 AWS 내의 Seoul 지역을 사용하여 만들어주었다. (무료 옵션에 서울이 있다니 좋다)

클러스터

DB를 돌릴 수 있는 서버까지 생성이 되었다면, 서버에 대한 접근 권한을 줄 수 있도록 설정해야한다.

  • Network Access : DB에 접근할 수 있는 IP를 설정 (만약 나중에 서버를 배포한다면 해당 서버의 ip를 작성해줘야 하며, 지금은 내 주소의 ip를 적어주었다)
  • Database Access : 사용자 자격 증명을 통해 DB에 접근할 수 있도록 유저 생성 (비밀번호를 통해 생성하는 방식을 사용했으며, DB에 읽고 쓰는 권한만 부여했다)

여기까지 작업해주었다면 DB 설정은 끝났다! 이제 nodejs 서버를 사용하여 연결해주자.

node.js, express 서버 설정하기

npm install --save mongodb

명령어를 통해 node.js 서버에 설치해주자. 자세한 연결 방법은 공식문서를 참고하자. 위 명령어는 DB를 설치한 것은 아니고, DB와 상호작용이 가능한 SDK를 설치한 것이다. Mongo Client를 사용하여 Mongo Client 인스턴스를 생성하고 특정 서버에 연결되어 있는지 확인하자.

다음의 코드를 통해 Mongo Client를 생성할 수 있다.

const MongoClient = require("mongodb").MongoClient;

여기까지 해준 뒤, 다시 Mongo Altas로 돌아가서 실제로 연결해줄 수 있는 링크를 가져오자.


위 화면에서 Drivers를 눌러주면 된다.

연결이 가능한 링크가 생성되는데 링크를 살펴보자.

const url =
  "mongodb+srv://yeji:<password>@willing-db.ppf64bo.mongodb.net/?retryWrites=true&w=majority";

.net/ 뒤에 컬렉션을 작성해주면 된다.
DB에 있는 컬렉션에 있는 문서(현재 프로젝트의 경우 todos 데이터가 될 것)를 작성해주자.
.net/todos_test?retry...와 같이 작성되면 된다.

실제로 DB에 데이터 생성하기

const MongoClient = require("mongodb").MongoClient;

const url =
  "mongodb+srv:....";

const createTodo = async (req, res, next) => {
    const newTodo = {
        text: req.body.text,
        id: req.body.id,
        isDone: req.body.isDone,
        groupId: req.body.groupId,
        dueDate: req.body.dueDate,
        createDate: req.body.createDate,
    }
    const client = new MongoClient(url);
}

const getTodos = async (req, res, next) => {
    
}

exports.createTodo = createTodo;
exports.getTodos = getTodos;

createTodo 함수 내에 존재하는 데이터는 프론트엔드에서 설계해둔 인터페이스를 기반으로 뽑아내기 위해 작성했다.
const client = new MongoClient(url); 이 코드는 MongoDB와 Mongo Client에게 연결할 서버에 대한 정보를 알려주는 것이고 연결을 실행하는 것은 아니다!

실제 연결을 수행할 부분은 연결이 실패하는 경우를 처리할 수 있도록 try catch 구문으로 감싸서 작성해주자.

    try {   
        
    } catch(error) {
        return res.json({message: "Fail to store data."})
    }

만약 연결이 실패한 경우에는 연결에 실패하였다는 메세지를 담은 응답을 보내주고, 함수의 실행을 멈추기 위해 return을 작성해주었다.

const db = client.db();

db() 함수에 따로 인자를 넘겨주지 않는 경우 위에서 생성한 url를 가져온다. 데이터베이스에 접근했으니 해당 DB의 컬렉션에 접근하자.

const todos = db.collection("todos");
const result = await todos.insertOne(newTodo);

collection() 메서드에 전달되는 인자는 컬렉션의 이름이다. 만약 해당 이름의 컬렉션이 존재하지 않는 경우에는 mongoDB가 생성해주며, 존재한다면 그 컬렉션에 작업을 수행한다. 지금 케이스는 하나의 요소만 컬렉션에 삽입해줄 것이므로 위와 같이 작성했다.

여기까지 작성해주면 .collection()을 통해 DB 연결까지 수행했고 새로운 문서도 작성했으며 오류 상황까지 잡아낼 수 있게 되었다. 이제 마지막으로 연결 종료까지 설정해주자. (connection이 계속 열려 있는 상황은 바람직하지 않다) 생성한 newTodo를 전송해주는 것까지 작성한 최종 메서드는 다음과 같다.

const createTodo = async (req, res, next) => {
  const newTodo = {
    text: req.body.text,
    id: req.body.id,
    isDone: req.body.isDone,
    groupId: req.body.groupId,
    dueDate: req.body.dueDate,
    createDate: req.body.createDate,
  };
  const client = new MongoClient(url);

  try {
    const db = client.db("todos_test");
    const todos = db.collection("todos");
    const result = await todos.insertOne(newTodo);
  } catch (error) {
    return res.json({ message: "Fail to store data." });
  }

  client.close();
  res.json(newTodo);
};

이제 위 파일과 app.js 파일을 연결해주자.

const express = require("express");
const app = express();
const mongoDB = require("./database/mongo");

app.post("/todos", mongoDB.createTodo);

app.listen(5000, () => console.log("Server is running at 5000 ✨"));

서버를 가동하고 postman을 사용하여 실제로 post요청을 보내보면 잘 들어가는 것을 볼 수 있다.

DB에서 데이터 불러오기

collection 내에 존재하는 모든 데이터를 불러오는 코드는 더 간단하다. 넣을 자료형을 정의해줄 필요 없이, 데이터만 가져와서 res에 담아 보내주면 된다.

const getTodos = async (req, res, next) => {
  const client = new MongoClient(url);
  let todos;
  try {
    const db = client.db("todos_test");
    const todos_collection = db.collection("todos");
    todos = await todos_collection.find().toArray();
  } catch (error) {
    return res.json({ message: "Fail to retrieve data." });
  }

  client.close();
  res.json(todos);
};

exports.getTodos = getTodos;

todos_collection.find().toArray(); find 메서드는 모든 데이터를 가져와 커서처럼 가리키고 있어 모든 데이터를 가져오기 위해 toArray 메서드를 실행해주었다.

실행해보면 데이터가 잘 넘어오는 걸 볼 수 있다.

너무 작업이 번거롭다!

작성하다보면 db 연결할 때마다 열고 닫고 가져오고 반복되는 코드도 많고 귀찮다. 그래서! 훨씬 mongoDB와 상호작용하기 쉽게 만들어주는 mongoose를 설치해보려 한다.

profile
함께 일하고 싶은 개발자가 되기 위해 노력합니다. 코딩테스트 관련 공부 및 이야기는 티스토리에도 업로드되어 있습니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 23일

좋은 정보 얻어갑니다, 감사합니다.

답글 달기