1. MongoDB Atlas에서 DB 셋팅하기
1) 프로젝트 생성
프로젝트 이름 입력 후 다음 클릭
프로젝트에 멤버를 추가할 수 있는데 현재 나는 혼자 진행 중이기에 패스하고 생성 버튼을 클릭했다!
2) Database 생성하기
Build a Database 클릭
무료로 사용하기 위해 마지막 옵션 선택
지역을 선택한다. 현재 내 위치에서 가장 가까운 곳으로 설정해야 한다고 한다!
Cluster 이름까지 기입하면 끝! (나는 이름을 뭐라고 해야 할지 모르겠어서 기본값으로 설정해 둔다...)
3) Database Setting
빌드를 마친 후, 왼쪽 사이드바에서 Database Acess로 들어가 DB 사용자를 추가한다.
아이디와 비밀번호를 설정하고, Built-in-Role을 Atlas admin으로 설정한다.
이렇게 설정해 줘야 해당 아이디로 DB 접속 시 제약 없이 모든 걸 할 수 있다고 한다.
비밀번호는 설정 후에 다시 확인할 수 없기 때문에(재설정은 가능) 잘 기록해 두도록 하자
Network Acess 페이지로 넘어와 IP를 추가한다.
'ADD CURRENT IP ADDRESS'를 누르면 현재 내 IP 주소가 자동으로 추가된다.
단순히 개발중일 때는 집이 아닌 다른 곳에서도 작업할 수 있으니 Allow access from anywhere를 누르거나 0.0.0.0/0을 추가해도 괜찮다. 하지만 배포 시에는 신뢰할 수 있는 IP만 추가해야 한다.
2. Next.js와 연결하기
1) 작업 폴더 터미널에서 mongodb 라이브러리 설치
npm install mongodb
2) Database 접속 Url 가져오기
connect 클릭
Drivers 클릭
표시된 주소를 복사한다.
admin은 현재 사용자의 아이디이며, <password> 칸에는 사용자의 비밀번호를 넣어야 한다.
3) database.ts 파일 생성
// app/utils/database.ts
import { MongoClient } from 'mongodb'
const url =
'mongodb+srv://[아이디]:[비밀번호]@cluster0.dggv7bb.mongodb.net/?retryWrites=true&w=majority'
const options: any = { useNewUrlParser: true }
let connectDB: Promise<MongoClient>
if (process.env.NODE_ENV === 'development') {
// 개발 중 재실행을 막음
if (!global._mongo) {
global._mongo = new MongoClient(url, options).connect()
}
connectDB = global._mongo
} else {
connectDB = new MongoClient(url, options).connect()
}
export { connectDB }
Next.js의 경우 개발할 땐 파일을 저장할 때마다 자바스크립트 파일들이 재실행되기 때문에 MongoClient.connect가 동시에 여러 개 실행될 수 있다. 이 경우 DB 입출력이 매우 느려지기 때문에, 이를 방지하기 위해 개발 중일 때 전역변수 global에 보관하도록 한다. 실제 프로덕션 상태일 땐 global을 사용 안 하는 게 좋다고 하여 else 문이 추가되었다. (프로덕션 상태일 땐 중복실행될 일이 별로 없다고 한다.)
4) global.d.ts 작성
'typeof globalThis' 형식에 인덱스 시그니처가 없으므로 요소에 암시적으로 'any' 형식이 있습니다. ts(7017)
타입스크립트를 사용 시 database.ts의 코드를 작성하면 위와 같은 오류가 발생한다.
globalThis에 _mongo라는 속성이 들어갈 수 있다고 설정해줘야 한다.
최상위 폴더에 global.d.ts를 추가하고 다음과 같이 작성한다.
// global.d.ts
import type { MongoClient } from 'mongodb'
declare global {
namespace globalThis {
var _mongo: Promise<MongoClient>
}
}
참고
3. Next.js에서 MongoDB 데이터 입출력 해보기
간단한 게시판 기능을 만들어 보며 DB 데이터 입출력을 해보았다.
1) DB에 데이터 저장 해보기
// app/write/page.tsx
export default function Write() {
return (
<div className="p-20">
<h4>글작성</h4>
<form
action="/api/post/new"
method="POST"
style={{ display: 'flex', flexDirection: 'column' }}
>
<input name="title" placeholder="제목"></input>
<textarea name="content" placeholder="내용"></textarea>
<button type="submit">제출</button>
</form>
</div>
)
}
// pages/api/post/new.ts
import { connectDB } from '@/util/database'
import { NextApiRequest, NextApiResponse } from 'next'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
if (req.method === 'POST') {
if (req.body.title !== '' && req.body.content !== '') {
try {
const db = (await connectDB).db('forum')
let result = await db.collection('post').insertOne(req.body)
return res.redirect(302, '/list')
} catch (error) {
return res.status(500).json('DB 저장 오류')
}
}
}
return res.status(500).json('내용을 입력해주세요!')
}
DB에 저장하는 부분은 이 부분이 전부다.
import { connectDB } from '@/util/database'
...
const db = (await connectDB).db('forum')
let result = await db.collection('post').insertOne(req.body)
2) DB에서 데이터 가져오기
import { connectDB } from '@/util/database'
import ListItem from './LIstItem'
export const dynamic = 'force-dynamic'
export default async function List() {
const db = (await connectDB).db('forum')
let result = await db.collection('post').find().toArray()
return (
<div className="list-bg">
<ListItem result={result} />
</div>
)
}
* DB 입출력은 서버(서버 컴포넌트)에서만 수행해야 한다.
'Develop > NextJS' 카테고리의 다른 글
[Next.js] 서버 & 클라이언트 컴포넌트에서 토큰 관리하기 (0) | 2024.07.24 |
---|---|
[Next.js] Data fetching과 Caching Mechanism (0) | 2024.06.12 |
[Next.js] Next.js 작업물 Vercel로 배포하기 (0) | 2023.07.21 |
[NextAuth] 커스텀 로그인 구현과 회원 정보 수정 (+ session update) (0) | 2023.07.14 |
[Next.js] Next.js에 Prettier 적용하기 (2) | 2023.06.08 |