티스토리 뷰
앞전에 1. 몽고디비 계정과 클러스터를 생성했고,
2. 몽구스(몽고디비 다루는 모듈)를 설치했고,
3. VSCode와 몽고디비를 연결하고 테스트까지 완료했다.
관련 게시글은 아래 링크를 참고한다.
https://dev-traveler.tistory.com/64
[Node.js] 몽고DB 시작하기, VSCode에서 몽고디비 연결하기
데이터베이스 비교관계형 데이터베이스 (RDBMS)NoSQL 데이터베이스저장할 자료의 구조를 행과 열로 된 표 형태로 관리문서 형태로 자료 저장SQL을 사용해서 SQL 데이터베이스라고도 함SQL을 사용하
dev-traveler.tistory.com
이제 몽고디비를 이용하여 CRUD 기능을 만들어 줄 것이다.
주요 함수 소개
아래 함수들은 mongoose의 내장 함수이다.
create 함수 : 데이터베이스에 새로운 도큐먼트를 만듦
Contact.create( { name: 'Kim', email: 'kim@google.com', phone: '12345'} )
find 함수 : 조건에 맞는 도큐먼트 찾음. 조건을 지정하지 않으면 모든 도큐먼트 찾음
Contact.find()
Contact.find( {name: 'Kim'} )
findOne 함수 : 조건에 맞는 도큐먼트가 여러개일 경우 첫 번째 도큐먼트 가져옴
Contact.findOne( {name: 'Kim'} )
updateOne, updateMany 함수
- updateOne : 조건에 맞는 첫번째 도큐먼트만 업데이트
- updateMany : 조건에 맞는 모든 도큐먼트 업데이트
// name="Kim" 인 도큐먼트 중 첫번째 도큐먼트의 phone 값을 45678로 변경
Contact.updateOne( {name: 'Kim'}, {phone: '45678'} )
deleteOne, deleteMany 함수
- deleteOne : 조건에 맞는 첫번째 도큐먼트만 삭제
- deleteMany : 조건에 맞는 모든 도큐먼트 삭제
// name='Kim'인 도큐먼트를 모두 삭제
Contact.deleteMany( { name: 'Kim'} )
findById 함수 : 아이디 값을 기준으로 도큐먼트 조회
Contact.findById('12345')
findByIdAndUpdate, findByIdAndDelete 함수 : 지정한 id에 해당하는 도큐먼트를 업데이트하거나 삭제한다
// Contact 데이터베이스에서 id값으로 자료를 찾고, name, email, phone 업데이트
Contact.findByIdAndUpdate(id, {name, email, phone} );
// 삭제할 때는 id만 지정하면 됨. 요청본문(req.body)에 포함된 id를 기준으로 자료를 찾아서 삭제
Contact.findByIdAndDelete( req.param.id );
여기서 Contact는 스키마를 이용해 만든 모델의 이름을 뜻한다.
앞전에 mongoose.Schema를 통해 스키마를 작성하고, mongoose.model로 스키마와 모델명을 지정했었다.
관련 게시글은 아래 링크를 참고한다.
https://dev-traveler.tistory.com/65
[Node.js] 몽고DB 주요 개념(도큐먼트, 컬렉션, 스키마), 스키마 생성
도큐먼트(Document) : MongoDB에서 데이터를 저장하는 기본단위(JSON 형태), 관계형 데이터베이스에서 행(Row)에 해당함컬렉션(Collection) : 도큐먼트 들이 모여있는 그룹, 관계형 데이터베이스에서 테이
dev-traveler.tistory.com
몽고디비로 CRUD 구현하기
myContacts > models > contactModel.js
const mongoose = require('mongoose');
const contactSchema = new mongoose.Schema({
name :{
type : String,
required : true
},
email : {
type : String,
},
phone : {
type : String,
required: [true, "전화번호는 꼭 기입해 주세요."]
}
},
{
timestamps : true
})
//스키마를 모델로 변환 : mongoose.model(모델명, 스키마명)
const Contact = mongoose.model("Contact" ,contactSchema);
module.exports = Contact;
위와 같이 스키마를 작성하였고, Contact 라는 모델로 변환하여 모듈로 내보내주었다.
컨트롤러가 이 모듈을 가져다가 CRUD 작업을 진행하면, 이 스키마를 따르게 된다.
myContacts > routes > contactRoutes.js
const express = require('express');
const router = express.Router();
const { getAllContacts
, createContact
, getContact
, updateContact
, deleteContact
} = require('../controllers/contactController')
//목록조회, 데이터 저장
router.route("/")
.get(getAllContacts)
.post(createContact)
;
//(특정 id) 조회, 수정 삭제
router.route("/:id")
.get(getContact)
.put(updateContact)
.delete(deleteContact)
;
module.exports = router;
URL 경로와 HTTP 요청 별로 contactController 함수를 매핑해주었다.
myContacts > controllers > contactController.js
const asyncHandler = require('express-async-handler');
const Contact = require('../models/contactModel');
// Get All contacts
// Get /contacts
const getAllContacts = asyncHandler(async(req, res) => {
const contacts = await Contact.find(); //데이터 전체 조회
res.send(contacts);
});
// Create contact
// Post /contacts
const createContact = asyncHandler(async(req, res) => {
const {name, email, phone} = req.body;
if(!name || !email || !phone){
return res.send("필수 값이 입력되지 않았습니다.");
}
//데이터 신규 저장
const contact = await Contact.create({name, email, phone});
res.send("데이터 생성 완료");
});
// Get Contact
// Get /contacts/:id
const getContact = asyncHandler(async(req, res) => {
const contact = await Contact.findById(req.params.id); //id로 조회
res.send(contact);
});
// update Contact
// Put /contacts/:id
const updateContact = asyncHandler(async(req, res) => {
const id = req.params.id;
const {name, email, phone} = req.body; //화면에서 새로 입력한 내용
const contact = await Contact.findById(id);
if(!contact){
throw new Error("Contact not found.");
}
//조회해온 contact 내용을 새로 입력한 name,email,phone 값으로 교체
contact.name = name;
contact.email = email;
contact.phone = phone;
await contact.save(); // update
res.json(contact); //화면에 결과표시
});
// delete Contact
// Delete /contacts/:id
const deleteContact = asyncHandler(async(req, res) => {
const id = req.params.id;
const contact = await Contact.findById(id);
if(!contact){
throw new Error("Contact not found.");
}
await Contact.deleteOne();
res.send("deleted!");
});
module.exports = {
getAllContacts
, createContact
, getContact
, updateContact
, deleteContact
};
상단에 Contact 모델을 require문으로 가져온다.
/contacts 경로로 오는 GET, POST 요청과
/contacts/:id 경로로 오는 GET,PUT,DELETE 요청
총 다섯가지 경우의 라우팅에 매핑될 함수를 각각 작성했다.
*** 여기서 중요한점은 Contact에 점(.) 찍고 CRUD 함수 호출 시, 반드시 await 선언을 함께 해줘야 한다. CRUD 작업 후, 그 아래줄 코드가 실행되게 하기 위함이다. ***
썬더 클라이언트로 테스트 하기
POST 요청으로 localhost:3000/contacts 로 접근할 경우는 데이터 생성일 경우이다.
Body > JSON 영역에 데이터 작성 후 Send 해보았다.
Response가 잘 뜨는 것을 확인했다.
앞전에 VSCode에 몽고디비 확장 프로그램을 연결해두었다.
나뭇잎 아이콘을 클릭하여 DB를 확인해보자.
맨 처음엔 admin과 local 데이터베이스만 있었는데,
POST 요청 테스트 후 확인해보니 myContacts 라는 데이터베이스와 그 아래 contacts 컬렉션이 생성되었다.
contacts 안에 Documents 1건이 등록되었는데, 해당 데이터를 클릭하면 아까 입력한 값이 들어있는 걸 확인할 수 있다.
도큐먼트의 id는 중복되지 않은 값으로 생성되었고, createdAt, updatedAt 은 스키마 작성 시 {timestamps:true} 옵션에 의해 자동 생성되었다.
* 데이터베이스 명 myContacts는 어떻게 생성되었나
몽고디비 연결 시, 커넥션 주소에는 디비에 접근 권한이 있는 id와 비밀번호가 포함된다.
이 값은 다른 사람들에게 노출되면 안 되므로, .env 파일에 환경변수로 등록하여 관리하는 게 좋다.
.env 파일에 DB_CONNECT 라는 환경변수를 등록하였고, 커넥션 주소 뒤에 /myContacts 라고 작성하였다.
이 말은 몽고디비 커넥션 주소 아래에 myContacts 라는 데이터베이스 밑으로 연결하겠다. 라는 뜻이다.
데이터를 최초 1건 넣을 때 myContacts 라는 이름으로 데이터베이스가 자동 생성된다.
* 데이터베이스 아래 컬렉션 명 contacts는 어떻게 생성되었나
contactModel.js 에서 스키마를 모델로 변환할 때, 모델명을 "Contact"라고 지정했다.
이 Contact 를 소문자로 변경 후, 뒤에 s를 붙여서 생성되는 게 일반적인 규칙이다.
나머지 테스트하기
POST, localhost:3000/contacts (데이터 단건 생성)으로 데이터를 각기 다른 값으로 여러 건 넣어주었고,
GET , localhost:3000/contacts 로 전체 데이터 조회 테스트를 완료했다.
GET localhost:3000/contacts/:id (데이터 1건 조회) 테스트
PUT localhost:3000/contacts/:id 로 name, email, phone 변경 후,
GET localhost:3000/contacts/:id 로 데이터 바뀐 것 확인 완료 (updatedAt 도 함께 갱신됨)
DELETE localhost:3000/contacts/:id 로 데이터 삭제 후
GET localhost:3000/contacts/:id 로 조회되는 건 없는 것 확인
https://youtu.be/YSGb-DX32ag?feature=shared
'백엔드 > Node.js' 카테고리의 다른 글
[Node.js] 라우터, 컨트롤러 분리하기 (0) | 2025.02.25 |
---|---|
[Node.js] 몽고DB 주요 개념(도큐먼트, 컬렉션, 스키마), 스키마 생성 (0) | 2025.02.16 |
[Node.js] 몽고DB 시작하기, VSCode에서 몽고디비 연결하기 (0) | 2025.02.15 |
[Node.js] 바디파서 미들웨어 (0) | 2025.02.15 |
[Node.js] express의 미들웨어, 라우터 미들웨어, 라우팅 파일 분리 (0) | 2025.02.13 |