
9. React.js와 Node.js 웹서버
1. Express
1) Express 란
: 빠르고 최소화된 웹 프레임워크
2) 웹 프레임워크
: 웹을 쉽게 만들수 있도록 도와주는 프레임워크
통신, DB, 쿠키 및 세션 관리, HTTP 구성, 라우팅 등의 기능을 구현해둔 것
우리는 웹 프레임워크 중 Express-generator 을 이용할 거고, npm 을 사용할 예정이다 !
3) Express 시작하기
cd ..
cd <project name>
npm install // dependencies 모듈 설치
npm run start // scripts 'start' 실행
npm install -D nodemon // 파일의 변화를 자동으로 감지하여 remount 해서 node 실행
nodemon 을 install 하면 package.json 에 아래와 같은 코드가 자동 생성된다
이 부분은 직접 추가해준다
2. MVC 디자인 패턴
1) MVC란
Model : DB와의 커넥션을 담당하는 영역
View : 결과물을 생성하는 영역
Controller : Model과 View를 핸들링하고, 로직을 처리하는 영역
index.ejs 가 뷰임
EJS (Embeded JavaScript) : HTML 안에 JavaScript를 삽입할 수 있도록 해주는 템플릿 엔진, html 로 되어 있지만 태그가 좀 다름 !
뷰 엔진 : Express에서 템플릿 엔진을 실제 렌더링 도구로 등록할 때 쓰는 설정 이름
템플릿엔진 : HTML에 서버 데이터를 끼워넣는 도구
routes 가 Controller, views 가 View 를 의미한다, Model 은 없으니까 만들어야 한다 !
우리는 뷰 엔진을 json 으로 쓸 거라서 기존에 있던 views 폴더를 삭제할 거다 !
app.js 에서 주석 처리한 부분을 지우고 아래와 같이 수정하면 된다
2) 라우팅
: 애플리케이션 엔드 포인트(URI)의 정의, 그리고 URI가 클라이언트 요청에 응답하는 방식
router 는 Controller 다: 요청을 받아 로직을 처리하고 응답을 보내준다
3) 라우터 만들고 등록하기
우리가 할 것은
→ 어떤 메소드로 요청을 받을 것인가? url '/' 로
→ 어떤 URL로 요청을 받을 것인가? get 요청을 받고
→ 어떤 로직을 처리할 것인가? 어떤 로직도 없이
→ 어떤 응답을 줄 것인가? 'This is Board' 를 응답으로 보냄
실습)
1. birds라는 router를 만드시오.
2. /birds 를 입력하면 Birds home page라는 응답을 주도록 하시오.
3. /birds/about 를 입력하면 About birds라는 응답을 주도록 하시오.
const express = require('express');
const router = express.Router();
router.get('/', function (req, res, next) {
res.send('Birds home page');
});
router.get('/about', function (req, res, next) {
res.send('About Birds');
})
module.exports = router;
// App.js 에 추가
const birdsRouter = require("./routes/birds");
app.use('/birds', birdsRouter);
7. MongoDB와 Mongoose
1. Database 란
1) Database
: 여러 사람에 의해 공유되어 사용될 목적으로 통합하여 관리되는 데이터의 집합
2) RDBMS - 전동적인 DB
Oracle, MariaDB, SQLite …
RDB : 관계형 데이터베이스
데이터가 일관적이지 않은 것을 싫어해서 제약을 많이 건다
3) NoSQL – Not Only SQL
mongoDB, 카산드라 …
덜 제한적인 일관성 모델을 이용하는 데이터의 저장 및 검색을 위한 매커니즘을 제공
단순 검색 및 추가 작업을 위한 매우 최적화된 키 값 저장 공간
RDBMS 와 관점이 다름
4) RDB vs NoSQL
- Redis : 하드디스크에 저장하니까 너무 오래 걸려서 메모리에 저장하자, 그런데 메모리는 휘발성이라는 단점도 있음, 응답에만 초점을 맞춘 것
- MongoDB : 데이터 중복을 없애려고 하다보니 조인이 많아지고 비용이 발생하고 관리가 힘들다, 그래서 구조를 json 으로 바꾸자, 그러면 조인 안 해도 데이터 가져올 수 있다!
DB의 신뢰성이 중요하면 → RDBMS
DB의 유연성과 확장성이 중요하면 → NoSQL
그런데 보통 서비스가 커지면 RDBMS 가 메인, NoSQL 을 서브로 둘 다 가져가게 됨
2. MongoDB란
1) MongoDB
MongoDB의 가장 큰 특징은 Schemaless ! RDBMS처럼 스키마가 존재하지 않아서 확장이 용이하고 수정이 편하다는 장점이 있다
2) MongoDB 사용하기
https://cloud.mongodb.com 에 들어가서 클러스터를 생성한다
Mongoose는 Node.js에서 MongoDB를 쉽게 다룰 수 있게 도와주는 라이브러리!
npm install mongoose
node src/index.js // 파일 실행
const mongoose = require("mongoose");
const DB_URL = "<url 복사>";
const Movie = require("./models/Movie");
const Review = require("./models/Review")
async function main() {
await mongoose.connect(DB_URL).then(() => {
console.log("Connection Success");
}).catch((err) => {
console.log(err);
});
// 2.1. Movie 추가 (684bb2760e3b57e1d2aa7a4e)
const movie = await Movie.create({
title: "영화1",
director: "신윤수",
startDate: "2017-01-18",
thumbnail:
"https://an2-img.amz.wtchn.net/image/v2/W-6OOBFuHj6lBaBEfctSjw.jpg?jwt=ZXlKaGJHY2lPaUpJVXpJMU5pSjkuZXlKdmNIUnpJanBiSW1SZk5Ea3dlRGN3TUhFNE1DSmRMQ0p3SWpvaUwzWXhMMjV5YW5kaE5uaDFZbWx2WW5kbmJuWjVZM0J3SW4wLlVxRm83bHNuaHU3dzc5aXBIVlYtU2prUFQxY29JYWV2TUdMNDBLaVg5eTQ",
story:
"비밀리에 제작된 위조 지폐 동판을 탈취하려는 내부 조직에 의해 작전 중 아내와 동료들을 잃게 된 특수 정예부대...",
tags: [2017, "액션", "한국"],
});
console.log(movie);
// 2.2. Review추가
const reviews = Array.from({ length: 3 }).map((_, idx) => {
return {
writer: "신윤수",
title: `리뷰제목-${idx}`,
content: `리뷰내용-${idx}`,
movie: "684bb390e47a42fd86c709c5",
};
});
const savedReview = await Review.insertMany(reviews);
console.log(savedReview);
// 2.3 Review 조회 (참조하고 있는 movie 를 포함해서 가져오기)
const review1 = await Review.find(); // movie 값은 objectID
console.log(review1);
// populate - movie 가 가지고 있는 objectID 에 해당하는 실제 객체 함께 조회
const review = await Review.find().populate("movie");
console.log(review);
// 2.4 Movie 조회(populate with reviews)
const movies = await Movie.findOne().populate("reviews");
console.log(movies);
// console.log(movies.reviews);
};
main();
다시 아래로 돌아와서!
9. React.js와 Node.js 웹서버
3. Express.js 에 Mongoose 사용하기
1) Postman 사용하기 - 요청 날리고 데이터 받아오기
vscode 에서 스키마를 정의한다 - 어떤 데이터를 가지는지 정의함, 이 데이터는 MongoDB 에 데이터를 어떤 형식으로 저장할지 결정함
const { default: mongoose } = require("mongoose");
const boardSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
content: {
type: String,
required: true
},
author: String,
createAt: {
type: Date,
default: Date.now
}
});
const Board = mongoose.model("Board", boardSchema);
module.exports = Board;
→ 라우터에서 POST 요청을 처리한다 - req.body 로 데이터를 받아서 Board.create() 로 MongoDB 에 저장
const express = require('express');
const router = express.Router();
const Board = require('../models/Board');
router.post("/", async function (req, res) {
const data = req.body;
console.log(data);
const board = await Board.create({
title: data.title,
content: data.content
});
res.json(board);
})
module.exports = router;
→ Postman 에 요청을 보낸다 - Express - Mongoose - MongoDB 순서대로 데이터가 들어가고, 응답으로 저장된 데이터(JSON)이 날아온다
→ GET 요청으로 불러온다 - Postman 에서 GET 요청을 보내면 저장된 데이터를 모두 응답으로 불러올 수 있다
router.get("/", async function (req, res) {
const boards = await Board.find(); // 모든 게시글 조회
res.json(boards);
});
POST 로 요청할 때는 raw - JSON 형식을 선택하고 원하는 데이터를 입력한 후, 주소로 Send 요청을 보내면 된다. 그러면 아래와 같이 정보가 등록되는 걸 볼 수 있다.
GET 형식으로 요청할 때는 주소로 Send 요청을 보내면 그동안 쌓아둔 데이터를 불러올 수 있다.
실습)
게시판 만들기
// /models/Board.js
const { default: mongoose } = require("mongoose");
const boardSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
content: {
type: String,
required: true
},
author: String,
createAt: {
type: Date,
default: Date.now
}
});
const Board = mongoose.model("Board", boardSchema);
module.exports = Board;
// /routes/board.js
const express = require('express');
const router = express.Router();
const Board = require('../models/Board');
// POST 리소스 등록
router.post("/", async function (req, res) {
const data = req.body;
console.log(data);
const board = await Board.create({
title: data.title,
content: data.content
});
res.json(board);
})
// GET /:<resourceId> : 특정 resource 조회
router.get("/", async function (req, res) {
const boards = await Board.find(); // 모든 게시글 조회
res.json(boards);
});
router.get("/:boardId", async function (req, res) {
console.log(req.params);
const { boardId } = req.params;
const board = await Board.findById(boardId);
res.json(board);
})
// PUT /:<resourceId> : 특정 resource 수정
router.put("/:boardId", async function (req, res) {
const { boardId } = req.params;
const data = req.body;
const { title, content } = data;
const updatedBoard = await Board.findByIdAndUpdate(
boardId,
data,
{ new: true } // ← 업데이트된 결과를 리턴함
);
res.json(updatedBoard);
})
// DELETE /:<resourceId> : 특정 resource 삭제
router.delete("/:boardId", async function (req, res) {
const { boardId } = req.params;
const deleteBoard = await Board.findByIdAndDelete(boardId);
res.json(deleteBoard);
})
module.exports = router;
// App.js 에 추가
const boardRouter = require("./routes/board");
app.use('/board', boardRouter);'Education > 신한투자증권 프로 디지털 아카데미' 카테고리의 다른 글
| Next.js App Router, 서버 컴포넌트와 클라이언트 컴포넌트 알아보기 (1) | 2025.06.21 |
|---|---|
| JWT, Session, OAuth 인증 이해하기 (1) | 2025.06.21 |
| React hook 알아보기 (3) | 2025.06.10 |
| React useState, useEffect 파헤쳐보기 (1) | 2025.06.09 |
| TypeScript 기초 & React 기초 (2) | 2025.06.08 |