무료로 사용 가능한 NoSQL 방식의 데이터베이스. 따로 SQL문을 작성할 필요가 없으며 코드를 사용하여 DB에 접근하고 처리할 수 있다. 진입장벽이 낮다는 장점이 있다!
https://www.mongodb.com/ko-kr 사이트에 접속하여 시작하면 된다. 내 컴퓨터에서 직접 DB를 작동시킬 수 있는 서버를 가동해도 되지만 평생 컴퓨터 안 끌 자신이 없으니 서버를 사용하자. 다행히 평생 무료로 DB를 돌릴 수 있는 서버를 제공해주는 옵션이 있다. MongoDB Atlas를 사용하여 Free FOREVER 옵션을 갖는 클러스터를 만들어주자. Shared 옵션으로 AWS 내의 Seoul 지역을 사용하여 만들어주었다. (무료 옵션에 서울이 있다니 좋다)
DB를 돌릴 수 있는 서버까지 생성이 되었다면, 서버에 대한 접근 권한을 줄 수 있도록 설정해야한다.
여기까지 작업해주었다면 DB 설정은 끝났다! 이제 nodejs 서버를 사용하여 연결해주자.
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...
와 같이 작성되면 된다.
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요청을 보내보면 잘 들어가는 것을 볼 수 있다.
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를 설치해보려 한다.
좋은 정보 얻어갑니다, 감사합니다.