본문 바로가기

작업실/쭈군_작업실

nextjs + mongodb 연결

https://www.mongodb.com/developer/how-to/nextjs-with-mongodb/

 

How to Integrate MongoDB Into Your Next.js App

Learn how to easily integrate MongoDB into your Next.js application with the official MongoDB package.

www.mongodb.com

위 사이트 들어가서 따라 하는 게 제일 편하다.

하지만, 위 방식대로 하면 util/mongodb.js 에 있는 함수중 호출하라는 함수가 없었다.

그래서 다른 곳에 있는 코드를 가져와서 추가하였다.

그리고 db 커넥션 확인하는 부분이 deprecated 된 부분이라서 좀 수정할 필요가 있어서,

기본 형태로 프로젝트를 생성한 뒤, 몽고디비 관련 내용을 추가해주는 형태로 작업하기로 결정하였다.

 

  1. npm i -g create-next-app 또는 yarn global add create-next-app
  2. npx create-next-app myapp
  3. cd myapp
  4. npm i 또는 yarn install
  5. npm i mongodb 또는 yarn install mongodb
  6. https://www.mongodb.com/ 회원가입.
    회원가입 후 맨 위에 있는 블로그 내용을 따라서 load sample dataset까지 진행.
  7. 프로젝트 root에서 .env.local 파일 생성.

아래처럼 입력 후, '<USERNAME>', '<PASSWORD>'에 데이터베이스 생성 시 입력한 계정 정보 입력. 

MONGODB_URI=mongodb+srv://<USERNAME>:<PASSWORD>@cluster0.tdm0q.mongodb.net/sample_mflix?retryWrites=true&w=majority
MONGODB_DB=sample_mflix

이후 프로젝트 루트에 'lib' 폴더 생성.

lib 폴더로 이동 후, 'mongodb.js' 파일을 생성하고, 아래 코드를 mongodb.js 에 작성.

import { MongoClient } from 'mongodb';

const uri = process.env.MONGODB_URI;
const options = {
	useUnifiedTopology: true,
	useNewUrlParser: true,
};

let cachedClient;
let cachedDb;

if (!process.env.MONGODB_URI) {
	throw new Error('Please add your Mongo URI to .env.local');
}

export const connectToDatabase = async () => {
	// check the cached.
	if (cachedClient && cachedDb) {
		// load from cache
		return {
			client: cachedClient,
			db: cachedDb,
		};
	}

	// Connect to cluster
	let client = new MongoClient(uri, options);
	await client.connect();
	let db = client.db(process.env.MONGODB_DB);

	cachedClient = client;
	cachedDb = db;

	return {
		client: cachedClient,
		db: cachedDb,
	};
};

const ncDatabase = async (req, res, next) => {
	if (!(cachedClient && cachedDb)) {
		const connectObj = await connectToDatabase();
		req.dbClient = connectObj.client;
		req.db = connectObj.db;
	} else {
		req.dbClient = cachedClient;
		req.db = cachedDb;
	}
	return next();
};

export default ncDatabase;

 

 

public/index.js에 아래 코드를 추가.

... index.js

export const getServerSideProps = async (context) => {
	const { client } = await connectToDatabase();

	console.log(client.topology.s.state);

	// client.db() will be the default database passed in the MONGODB_URI
	// You can change the database by calling the client.db() function and specifying a database like:
	// const db = client.db("myDatabase");
	// Then you can execute queries against your database like so:
	// db.find({}) or any of the MongoDB Node Driver commands

	const isConnected = client.topology.s.state === 'connected';

	return {
		props: { isConnected },
	};
};

위 블로그에서 시키는 대로 만들면 index.js 하단에 'const isConnected = client.isConnected();' 코드가 있다.

나는 따로 mongodb 를 추가해서 설정하였는데, 'client.isConnected()' 이 함수가 deprecated 되어있었다.

그래서 DB 커넥션 확인하는데 없는거 호출한다고 계속 에러남..

콘솔 찍어보니까 저 위치에 연결 상태가 있길래 가져다 썼다.

 

그리고 index.js를 아래와 같이 수정.

'{isConnected ? ' 부분은 <main></main> 안에 아무 곳이나 추가해줘도 무방.

...

export default function Home({ isConnected }) {

...

				{isConnected ? (
					<h2 className="subtitle">You are connected to MongoDB</h2>
				) : (
					<h2 className="subtitle">
						You are NOT connected to MongoDB. Check the <code>README.md</code> for instructions.
					</h2>
				)}

				<p className={styles.description}>
					Get started by editing <code className={styles.code}>pages/index.js</code>
				</p>
                
...

그리고  yarn dev로 실행해보면

mongodb 연결 성공.

db에 연결되었는지 확인 가능.

진짜 연결되었는지 확인해봤다.

'pages/movies.js' 생성.

아래와 같이 코드 입력.

import React from 'react';
import { connectToDatabase } from '../lib/mongodb';

const Movies = ({ movies }) => {
	return (
		<div>
			<h1>Top 20 Movies of All Time</h1>
			<p>
				<small>(According to Metacritic)</small>
			</p>
			<ul>
				{movies.map((movie, key) => (
					<li key={key}>
						<h2>{movie.title}</h2>
						<h3>{movie.metacritic}</h3>
						<p>{movie.plot}</p>
					</li>
				))}
			</ul>
		</div>
	);
};

export default Movies;

export const getServerSideProps = async () => {
	const { db } = await connectToDatabase();

	const movies = await db.collection('movies').find({}).sort({ metacritic: -1 }).limit(20).toArray();

	return {
		props: {
			movies: JSON.parse(JSON.stringify(movies)),
		},
	};
};

그리고 http://localhost:3000/movies 에 들어가 보면 데이터 가져와서 뿌려주는 것을 확인 가능하다.

반응형