순서
- 필요한 모듈 불러오기
- Express 서버 기본 설정
- MongoDB 연결 준비
- 서버 시작 함수
- 메모 조회 API
- 메모 추가 API
- 메모 수정 API
- 메모 삭제 API
필요한 모듈 불러오기
const express = require("express")
const path = require("path")
const { MongoClient, ObjectId, ReturnDocument } = require("mongodb")
- express : 서버를 쉽게 만들게 해주는 라이브러리, app.get() app.post() 등 사용 가능
- path : 파일 경로를 다룰 때 사용
- MongoClient : MongoDB에 연결하는 객체를 만들 때 사용
- ObjectId : _id값을 다룰 때 사용
Express 서버 기본 설정
const app = express()
const PORT = 3000
app.use(express.json())
app.use(express.static(path.join(__dirname, "public")))
차례대로
- Express 서버 객체 생성, 앞으로 모든 API를 이 app에 붙여서 사용
- 포트 번호 정하기. 서버를 3000 포트에서 실행하겠다는 의미
- 클라이언트가 제이슨 형식으로 보낸 데이터를 읽을 수 있게 해줌
- public 폴더 안의 html/css/js 파일을 브라우저에서 접근 가능하게 함 -> 프론트와 연결하기 위함
MongoDB 연결 준비
const url = "mongodb+srv://ysy:Q98RsUCtfPH1Enjq@cluster0.smoslc0.mongodb.net/"
const client = new MongoClient(url)
const dbName = "memo"
let memoCollection
차례대로
- MongoDB Atlas 접속 주소, 어떤 계정에 연결할지 적어둔 것(이 주소를 통해 실행 가능)
- MongoDB와 연결할 준비 객체 생성, 실제 연결은 따로 해야함
- 사용할 DB 이름(memo) 지정
- 컬렉션 변수, memos 컬렉션을 담아둘 변수. DB 연결 후 실제 값이 들어감
서버 시작 함수
async function startServer() {
try {
await client.connect()
console.log("MongoDB 연결 성공!!")
const db = client.db(dbName)
memoCollection = db.collection("memos")
app.listen(PORT, () => {
console.log("서버 실행 중...")
})
} catch (error) {
console.log("MongoDB 연결 실패: ", error)
}
}
startServer()
- MongoDB에 실제로 연결하는 함수를 만들고, 컬렉션을 가져오고, 서버를 실행하는 기능
- await client.connect()로 MongoDB와 연결
- const db = client.db(dbname) : memo 데이터베이스 가져오기
- memoCollection = db.collection("memos") : memo컬렉션 연결
- app.listen(PORT, () => {console.log("서버 실행 중..."} : 서버 실행
- startSever()로 서버 실행 기능을 가진 함수 실행
메모 조회 API
app.get("/memos", async(req, res) => {
try {
const { keyword } = req.query
let filter = {}
if(keyword && keyword.trim() !== "") {
filter = {
text: { $regex: keyword.trim(), $options: "i" }
}
}
const memos = await memoCollection.find(filter).sort({ createdAt: -1 }).toArray()
res.json({
success: true,
count: memos.length,
memos
})
}catch(error) {
console.log("메모 조회 오류: ", error)
res.status(500).json({
success: false,
message: "메모 조회 중 오류가 발생!"
})
}
})
- 조회 : get
- const {keyword} = req.query : url의 쿼리 문자열에서 keyword 값을 꺼냄
- let filter = {} : 빈 객체이기 때문에 전체 조회를 의미
- 키워드가 있고 공백만 있는 키워드가 아닌지 확인 => 진짜 존재하는 키워드라면 filter에 검색 조건 삽입
- $regex : 정규식 검색
- $options: "i" : 대소문자 구분 없이 검색
- => filter에는 키워드의 앞뒤 공백을 제거하고 대소문자 구분 없이 검색해 조건에 맞는 것들을 넣음
- memoCollecrion.find(filter) : filter 조건에 맞는 것들만 검색. {}라면 전체 조회
- json 형태로 값을 보내는데 성공 여부, 검색된 메모의 수, 메모 목록을 보냄
- 실패했다면 catch(error)로 가 오류 코드 발생
메모 추가 API
app.post("/memo", async(req, res) => {
try {
// { text: "메모값" }
const { text } = req.body
if(!text || text.trim() === "") {
return res.status(400).json({
success: false,
message: "메모 내용을 입력해주세요"
})
}
const newMemo = {
text: text.trim(),
createdAt: new Date()
}
await memoCollection.insertOne(newMemo)
const memos = await memoCollection.find().sort({ createdAt: -1 }).toArray()
res.status(201).json({
success: true,
message: "메모가 추가되었습니다.",
memos
})
} catch (error) {
console.log("메모 저장 오류: ", error)
res.status(500).json({
success: false,
message: "서버 오류가 발생!!"
})
}
})
- 추가 : post
- text를 req.body에서 꺼냄
- 메모 내용이 없거나 공백만 있으면 오류 반환
- 새 메모 객체를 만들고 앞뒤 공백을 제거한 텍스트와 새 날짜를 저장
- await memoCollection.insterOne(newMemo) : MongoDB에 실제로 새 메모 객체 저장
- 저장 후 메모 목록을 최신순으로 다시 가져옴
메모 수정 API
app.put("/memos/:id", async (req, res) => {
try{
const { id } = req.params
const { text } = req.body
// id가 MongoDB ObjectId 형식인지 검사하고 아니면 400에러를 반환
if(!ObjectId.isValid(id)) {
return res.status(400).json({
success: false,
message: "올바르지 않은 메모 id 형식!!"
})
}
if(!text || text.trim() === "") {
return res.status(400).json({
success: false,
message: "변경할 메모 내용을 입력해주세요"
})
}
const result = await memoCollection.findOneAndUpdate(
{ _id: new ObjectId(id) },
{
$set: {
text: text.trim(),
updatedAt: new Date()
}
},
{
returnDocument: "after"
}
)
if(!result) {
return res.status(404).json({
success: false,
message: "해당 id의 메모를 찾을 수 없습니다"
})
}
res.json({
success: true,
message: "메모가 수정되었습니다. (PUT)",
memo: result
})
}catch(error){
console.log("메모 수정 오류(PUT): ", error)
return res.status(500).json({
success: false,
message: "메모 수정 중 오류가 발생!!"
})
}
})
- 수정 : PUT
- :id : 수정할 메모의 id
- const {text} = req.body : 요청 body에서 수정할 새 메모 내용 text를 꺼냄
- (!text || text.trim() ==="") : 수정할 내용이 비어있거나 공백인지 검사
- const result = await memoCollection.findOneAndUpdate : MongoDB에서 메모 하나를 찾아 수정하고 그 결과를 result에 저장
- { _id: new ObjectId(id) } : 수정할 메모를 찾는 조건. _id가 전달받은 id와 같은 문서를 찾고 ObjectId로 바꿔서 비교
- 이후 메모를 새 값으로 바꾸고 앞뒤 공백 제거, 수정된 시간을 updateAt : new Date()로 저장
- returnDocument: "after" : 수정 후의 문서를 반환. 수정 완료된 메모 내용을 result로 받음
메모 삭제 API
app.delete("/memos/:id", async (req, res) => {
try {
const { id } = req.params
// ObjectId 형식 검사
if (!ObjectId.isValid(id)) {
return res.status(400).json({
success: false,
message: "id가 올바르지 않습니다."
})
}
// 삭제
const result = await memoCollection.deleteOne({
_id: new ObjectId(id)
})
if (result.deletedCount === 0) {
return res.status(404).json({
success: false,
message: "삭제할 수 있는 id가 없습니다."
})
}
// 삭제 후 전체 목록 조회
const memos = await memoCollection.find().sort({createdAt: -1}).toArray()
return res.json({
success: true,
message: "삭제 완료",
count: memos.length,
memos
})
} catch (error) {
console.log("삭제 오류:", error)
return res.status(500).json({
success: false,
message: "삭제 오류"
})
}
})
- 삭제 : DELETE
- const { id } = req.params : URL 파라미터에서 삭제할 메모의 id를 꺼냄
- if (!ObjectId.isValid(id)) : id가 MongoDB Objectid 형식인지 검사.
- isValid : 어떤 값이 조건에 맞는지 확인하고 t/f로 반환하는 함수
- const result = await memoCollection.deleteOne : 메모 1개를 삭제한 결과를 result에 저장
- (result.deletedCount === 0) : 삭제된 문서 수가 0개인지 검사
- const memos = await memoCollection.find().sort({createdAt: -1}).toArray() : 삭제 후 남은 메모 목록을 최신순으로 정렬해 하고 배열 형태로 가져옴
'Node.js' 카테고리의 다른 글
| 메모 앱 만들기 - frontend (0) | 2026.07.07 |
|---|---|
| MongoDB (0) | 2026.07.06 |
| Node.js - 2 (0) | 2026.06.29 |
| Node.js - 1 (0) | 2026.06.26 |