나의 개발 일지

[Node.js 스터디] mongoDB와 연결한 백엔드 설정 (feat. cors에러 해결 방법)

designer DK 2024. 10. 9. 13:14
728x90

강의를 통해 배우는 첫 백엔드 설정 예제를 진행해보았다.

 

mongoDB와 node.js를 연결하고 백엔드 설정을해서 프론트엔드와 소통하는 할일 앱을 만드는 과제.

 

사실 한번에 너무 방대한 양을 배우는 데다가 페이지가 잘게 쪼개져 있어서 아직도 좀 아리송한 부분들은 있지만 대략적으로는 백엔드와 프론트엔드가 어떻게 돌아가는지 알게 된 것 같다.

 

시작 전에 npm을 이용해서 express, mongoose, body-parser를 설치. (바디파서는 이제 설치 필요 없음)

express를 이용해서는 서버를 간편하게 열 수 있었고 mongoose를 이용해서 mongoDB 스키마를 설계할 수 있었다.

const express = require('express');
const mongoose = require('mongoose');
const indexRouter = require('./routes/index');
const cors = require("cors");

const app = express();

app.use(cors()); //제일 먼저 있어야 함
app.use(express.json());
app.use(indexRouter);


const mongoURI = `mongodb://127.0.0.1:27017/todo-app`

mongoose.connect(mongoURI).then(() => {
console.log('mongoose connected!');
}).catch((err) => {
console.log('DB connection fail!', err);
});

app.listen(5001, () => {
console.log('server on 5001!');
});

app.js

 

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const taskSchema = Schema({
task: {
type: String,
required: true
},
isComplete: {
type: Boolean,
required: true
}
},
{ timestamps: true }
);

const Task = mongoose.model('Task', taskSchema);

module.exports = Task;

model/Task.js

 

gpt에게 물어보니 body-parser는 최신 express를 설치하면 포함되어있다고해서 따로 필요 없다고 했다.

 

원래 설치를하고 불러와서 아래 코드를 해줬어야했는데

app.use(bodyParser.json());

 

이제 익스프레스만 설치하고 이렇게 적어주면 된다.

app.use(express.json());

 

api 관리는 라우팅이라는 방식으로 했는데 꽤 흥미있는 지점이었다.

아직 복잡하지 않은 코드여서 실효성이 크진 않았는데 파일이 복잡해지면 실효성이 클 것 같다.

const express = require('express');
const router = express.Router();
const taskApi = require('./task.api')

router.use('/tasks', taskApi);

module.exports = router;

routes/index.js

 

const express = require('express');
const taskController = require('../controller/task.controller');
const router = express.Router();

router.post('/', taskController.createTask);

router.get('/', taskController.getTask);

router.put('/:id', taskController.updateTask);

router.delete('/:id', taskController.deleteTask);

module.exports = router;

routes/task.api.js

 

가장 메인작업은 컨트롤러라는 파일에서 이루어졌다.

CRUD라 불리는 백엔드의 4가지 큰 기능을 여기서 세부적으로 짰다.

 

생성이나 읽기는 강의를 들어가며 큰 어려움 없이 짤 수 있었다.

const Task = require('../model/Task')
const taskController = {};


taskController.createTask = async (req, res) => {
try{
const {task, isComplete} = req.body;
const newTask = new Task({task, isComplete});
await newTask.save();
res.status(200).json({status:'ok', data:newTask});
} catch(err){
res.status(400).json({status:'fail', error:err});
}
};

taskController.getTask = async (req, res) => {
try{
const taskList = await Task.find({}).select("-__v");
res.status(200).json({status:'ok', data:taskList});
} catch(err){
res.status(400).json({status:'fail', error:err});
}
};

컨트롤러 코드 중 읽기, 생성 코드

 

 

그런데 업데이트 부분은 처음 마주하는 개념들이 많아서 햇갈렸는데 gpt에게 물어가며 조금씩 이해해갔다.

taskController.updateTask = async (req, res) => {
try {
const task = await Task.findById(req.params.id);
if (!task) {
throw new Error("App can not find the task");
}
const fields = Object.keys(req.body);
fields.map((item) => (task[item] = req.body[item]));
await task.save();
res.status(200).json({ status: "success", data: task });
console.log(fields);
} catch (error) {
res.status(400).json({ status: "fail", error });
}
};

taskController.deleteTask = async (req, res) => {
try {
const deleteItem = await Task.findByIdAndDelete(req.params.id);
res.status(200).json({ status: "success", data: deleteItem });
} catch (error) {
res.status(400).json({ status: "fail", error });
}
};

module.exports = taskController;

 

여기서 req.params.id는 프론트에서 url /tasks 뒷부분에 붙여보내는 id 값이며

이 값은 곧 mongoDB에서 자동생성된 고유 id 값이기도 하다.

 

const fields = Object.keys(req.body);

      fields.map((item) => (task[item] = req.body[item]));

 

이 코드도 햇갈렸었는데 분석해보면 프론트에서 보내는 바디 객체의 ‘키’ 값,

즉 키밸류 중 키 부분들만 fields라는 변수에 배열로 저장한다. 지금 예제의 경우 task와 isComplete라는 값이다.

 

프론트로부터 수정된 body값을 가져와서 map기능을 이용해서 기존 task에 덮어씌워 저장하는 방식.

 

delete도 req.params.id를 통해 제어한다는게 특이할 뿐 그 이상의 특이점은 없었다.

 

이렇게 첫 백엔드 구축 완료!

 

프론트엔드 구축 전 백엔드 테스트용으로 포스트맨 (post man)이라는 사이트를 이용해봤는데

쉽게 백엔드 테스트를 해볼 수 있어서 좋았다.

특히 포스트나 업데이트같은 부분은 프론트 구축이 안되어있으면 테스트가 힘든데 포스트맨을 이용하니 즉석으로 테스트 해볼 수 있었다.

postman으로 POST를 테스트한 장면

 

 

프론트엔드는 제대로 todo-app ui를 만들기 전에 서버와 통신이 잘 되는지만 간단하게 테스트 해보았다.

처음 시도하면 cors에러가 나는데 이를 해결하기 위해서는 npm install cors로 cors문제 해결 모듈을 설치해주고

const express = require('express');
const mongoose = require('mongoose');
const indexRouter = require('./routes/index');
const cors = require("cors");

const app = express();

app.use(cors()); //제일 먼저 있어야 함
app.use(express.json());
app.use(indexRouter);

 

서버측 app.js에서 이런식으로 cors를 가져와서 사용을 해줘야한다. (use(cors())의 순서 중요!)

 

 

일단 간단하게 네 개 버튼을 만들고 fetch api를 이용해서 내가 만든 서버 데이터를 가져와보는 테스트를 해보았고 생각보다 잘 가져와졌다.

프론트엔드 테스트

 

 

강의는 리액트 기반으로 프론트엔드가 구축되는데 나는 생 자바스크립트로 도전해볼 생각이다.

아직은 감을 잡아나가는 단계지만 백엔드는 백엔드만의 묘미가 있어 재미있게 느껴진다.