Next.js + MongoDB 연결

JoonPark·2023년 12월 8일
0
post-thumbnail

서론

Nodemailer로 고객이 문의 메일을 보냈을 때 회사 CS 메일로 내용을 보내주는 것은 구현을 해 놓았다.
이게 끝이 아니다. 이제 해당 내용을 데이터베이스에 연결해서 문의 내용을 데이터로 관리해야하는 니즈가 생겼다.
먼저 데이터베이스는 회사 구글 계정을 사용해 MongoDB Atlas 서비스를 사용했다.
데이터베이스 구축의 경우는 그냥 다른 게시글들을 보며 따라하면 되기에, 여기에 적지 않았다.

본론

일단은 mongoDB에 연결을 해야지

  • src/app/lib 경로에 mongodb.ts를 생성한다.
  • 왜 api 폴더에 넣지 않냐면, 유틸처럼 db에 연결할때 그냥 함수만 가져다 쓸 것이기 때문.
  • mongoDB 예제코드에서는 catch(error)문 대신 await client.close(); 명령어가 들어가 있는데, 이걸 수정하지 않고 사용했다가 DB에 연결되자마자 종료되어 조금 지체되었다(...)
// src/app/lib/mongodb.ts
// 환경 변수에서 MongoDB 연결 문자열을 가져옵니다.
const uri = process.env.MONGODB_URI;

// 연결 문자열이 없으면 에러를 던집니다.
if (!uri) {
  throw new Error("MONGODB_URI 환경 변수를 정의해주세요.");
}

// MongoDB 클라이언트를 생성합니다. 이 클라이언트는 MongoDB 서버와의 연결을 관리합니다.
const client = new MongoClient(uri, {
  // serverApi 옵션을 통해 MongoDB 서버 API 버전, 엄격 모드, 폐기 예정 에러 옵션을 설정합니다.
  serverApi: {
    version: ServerApiVersion.v1,
    strict: true,
    deprecationErrors: true,
  },
});

// MongoDB에 연결하는 함수를 정의합니다.
async function setMogoConnect() {
  try {
    // 클라이언트를 통해 MongoDB에 연결합니다.
    await client.connect();
    // 연결이 성공적인지 확인하기 위해 ping 명령을 보냅니다.
    await client.db("web").command({ ping: 1 });
    // 연결 성공 메시지를 콘솔에 출력합니다.
    console.log("Pinged your deployment. You successfully connected to MongoDB!");
  } catch (error) {
    // 에러가 발생하면 콘솔에 에러를 출력합니다.
    throw new Error();
  }
}

// MongoDB에 연결하는 함수를 실행하고, 에러가 발생하면 콘솔에 출력합니다.
setMogoConnect().catch(console.dir);

// MongoDB 클라이언트를 내보냅니다.
export { client }

데이터를 데이터베이스에 넣으려면?

  • 기본적으로 메일 발송버튼 클릭이라는 하나의 트리거에 '메일 발송', '데이터베이스에 데이터 저장' 두가지의 기능을 해야한다.
  • 함수 내에서 db에 연결하고, 이후 모든 과정이 끝난 후 db와 연결을 끊는 부분까지 코드로 작성했다.
// app/api/email/route.ts
export async function POST(req: NextRequest) {
  const body: IFormInput = await req.json();
  // 함수를 실행!!
  addContactData(body);
  // ... 이메일 보내기 코드
}

// MongoDB에 연락처 데이터를 추가하는 함수입니다.
async function addContactData(body: IFormInput) {
  // "web" 데이터베이스를 선택합니다.
  const db = client.db("web")
  // "contact" 컬렉션을 선택합니다.
  const collection = db.collection("contact")
  // 컬렉션에 데이터를 추가하고, 결과를 출력합니다.
  const result = await collection.insertOne(body)
  console.log(result)
  // 데이터 베이스 연결을 종료합니다.
  await client.close();
}

시행 착오

  • 테스트를 위해 메일 발송 부분은 제외하고 데이터 저장 부분만 진행했다가 NextResponse 부분이 없어서 고생했다...
  • 최근 Next.js의 api 요청 구조가 계속해서 바뀌어서 레퍼런스를 얻기 꽤 힘들었다.

결론

보완점

  • MongoDB를 mongoose모듈 ODM(Object Document Mapping : 객체와 문서를 1:1로 매칭)으로 개선해보자
  • mongoose를 사용해 스키마를 정의해보자
  • 스피너를 사용해 데이터 요청, 처리, 응답을 받기까지의 시간동안 로딩중임을 알려주자
profile
FE Developer

0개의 댓글