nextjs + mongo 연동하기

nextjs+ mongoDB 연동을 해보았다.

.env 설정

루트 디렉토리에 .env 파일을 만들어준다.
.gitignore가 존재할 경우 .env도 추가해주어야 한다.

.env

1
MONGODB_URL=mongodb+srv://<사용자명>:<사용자 비밀번호>@cluster0.gvztc.mongodb.net/<DB이름>?retryWrites=true&w=majority

mongooose 설치

nodejs와 연동하기 위해 mongoose 모듈을 설치해준다.

1
npm i mongoose

db 연결하기

캐시를 통해 핫리로드가 가능하게 하고 데이터베이스를 불러온다.

공식문서에서 가져왔다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import mongoose from "mongoose";

const MONGODB_URI = process.env.MONGODB_URI;

if (!MONGODB_URI) {
throw new Error(
"Please define the MONGODB_URI environment variable inside .env.local"
);
}

/**
* Global is used here to maintain a cached connection across hot reloads
* in development. This prevents connections growing exponentially
* during API Route usage.
*/
let cached = global.mongoose;

if (!cached) {
cached = global.mongoose = { conn: null, promise: null };
}

async function dbConnect() {
if (cached.conn) {
return cached.conn;
}

if (!cached.promise) {
const opts = {
bufferCommands: false,
};

cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
return mongoose;
});
}
cached.conn = await cached.promise;
return cached.conn;
}

export default dbConnect;

스키마 정의하고 모델 반환하기

스키마를 정의해주고 모델을 반환한다.
db에 해당 스키마가 존재하지 않을 경우 생성하고 모델을 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import mongoose from "mongoose";

const ProductSchema = new mongoose.Schema(
{
title: {
type: String,
required: true,
maxlength: 60,
},
desc: {
type: String,
required: true,
maxlength: 200,
},
img: {
type: String,
required: true,
},
prices: {
type: [Number],
required: true,
},
extraOptions: {
type: [
{
text: { type: String, required: true },
price: { type: Number, required: true },
},
],
},
},
{ timestamps: true }
);

export default mongoose.models.Product ||
mongoose.model("Product", ProductSchema);

사용하기

next.js에서는 api를 만드는 기능을 제공한다.
express와 비슷하다. RESTful한 API도 생성이 가능하다.

1
2
3
4
5
/pages/api/product/index.js 주소/api/product로 접근 가능

/pages/api/product/[id].js 주소/api/product/asdf로 {id:asdf}에 접근 가능

/pages/api/product/[...data].js 주소/api/user/의 하위 경로들로 전부 접근 가능

아래 코드는 주소/api/product를 통해 접근 가능하다.

/pages/api/products/index.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import dbConnect from "../../../util/mongo";
import Product from "../../../models/Product";
export default async function handler(req, res) {
const { method } = req;

dbConnect();

if (method === "GET") {
try {
const products = await Product.find();
res.status(200).json(products);
} catch (err) {
res.status(500, json(err));
}
}

if (method === "POST") {
try {
const product = await Product.create(req.body);
res.status(201).json(product);
} catch (err) {
res.status(500).json(err);
}
}
}