본문 바로가기
웹 프로그래밍/👨‍👨‍👧‍👧소셜 가계부

[React/Node.js/Express/MongoDB] 소셜 가계부 프로젝트 구현 일지: 몽고DB 연동 후 데이터 전송하기 (입출금 내역 POST, GET, PATCH, DELETE 요청)

by 청량리 물냉면 2024. 1. 28.
반응형

🚧 사전 작업

필요한 패키지 설치

npm install dotenv mongoose

 

MongoDB 드라이버 설치

npm install --save mongodb

 

데이터베이스와 상호작용할 수 있는 sdk 설치

 

 

MongoDB 아틀라스 접속 및 회원가입, 데이터 베이스 만들기

 

MongoDB 연결하기(1)

회원가입 로그인 부분은 생략 하였습니다.Whitelist IP 란 승인 된 컴퓨터 IP주소를 나열하여 현재 사용하는 컴퓨터와 상호 작용 할 수 있도록 필터링 하는 IP 입니다.Database Access 메뉴에 들어와 사용

velog.io

 

MongoDB Atlas 사용법 | 코드잇

MongoDB Atlas에 가입하고 데이터베이스 주소를 사용하는 방법에 대해 알아봅시다. | MongoDB Atlas를 사용하려면 가장 먼저 가입을 해야 합니다. [Atlas 회원 가입 페이지](https://www.mongodb.com/atlas/database)

www.codeit.kr

 

 

Mongoose 이용해 DB-백엔드 연동

app.js

require("dotenv").config();

const express = require("express");
...
const bodyParser = require("body-parser");
const { default: mongoose } = require("mongoose");

app.use(bodyParser.json());

app.use("/api/transactions", transactionsRouter);

...

mongoose
  .connect(process.env.MONGO_URI)
  .then(() => {
    //db 연결이 성공할 경우 서버 연결
    app.listen(5000);
  })
  .catch((err) => {
    console.log(err);
  });

 

 

Transaction 스키마 생성

models > transaction.js

const mongoose = require("mongoose");

const Schema = mongoose.Schema;

const TransactionSchema = new Schema({
  uid: { type: String, required: true },
  date: { type: Number, required: true },
  category: { type: String, required: true },
  title: { type: String, required: true },
  amount: { type: Number, required: true },
  memo: { type: String },
});

module.exports = mongoose.model("Transaction", TransactionSchema);

데이터베이스에 저장될 데이터를 정의하는 스키마를 생성한다. 

 

 

express-validator 설치

express 유효성 검증 모듈

npm install express-validator

 

 

+) models 폴더 > http-error.js 자체 에러 처리 모델 생성

class HttpError extends Error {
  constructor(message, errorCode) {
    super(message); //'message' 프로퍼티 추가
    this.code = errorCode; //'code' 프로퍼티 추가
  }
}

module.exports = HttpError;

 

 

🚧 백엔드 → DB  POST 요청 보내기

transactions-controller.js

const { v4: uuid } = require("uuid");
const { validationResult } = require("express-validator");

const HttpError = require("../models/http-error");
const Transaction = require("../models/transaction");

...

const createTransaction = async (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(HttpError(errors.array(), 422));
  }
  const { uid, category, title, amount, memo } = req.body;

  //모델 생성 완료
  const createdTransaction = new Transaction({
    uid,
    date: new Date().getTime(),
    category,
    title,
    amount,
    memo,
  });

  try {
    await createdTransaction.save();
  } catch (e) {
    const error = new HttpError("입출금 내역 저장 실패", 500);
    return next(error);
  }

  res.status(201).json({ transaction: createdTransaction });
};
...

포스트맨으로 post 요청을 보낸다
실제 db에 post 요청된 데이터가 저장되어 있는 모습

 

 

🚧 백엔드 → DB  GET 요청 보내기

transactions-controller.js > getTransactionById

const getTransactionById = async (req, res, next) => {
  const transactionId = req.params.tid; // type: string

  let transaction;
  try {
    transaction = await Transaction.findById(transactionId);
  } catch (e) {
    //GET 요청에 문제가 생겼을 때
    const error = new HttpError("입출금내역을 불러오지 못했습니다.", 500);
    return next(error);
  }

  // GET 요청에 문제가 없지만 입출금내역을 찾을 수 없는 경우 에러 핸들링
  if (!transaction) {
    const error = new HttpError(
      "해당 ID에 대한 입출금내역을 찾지 못했습니다.",
      404
    );
    return next(error);
  }

  res.json({ transaction: transaction.toObject({ getters: true }) });
};

mongoose 함수 findById를 이용해 params의 id와 일치하는 Transaction 스키마의 데이터를 찾아온다. 

GET 요청이 성공적으로 완료된 모습

 

transactions-controller.js > getTransactionsByUserId

const getTransactionsByUserId = async (req, res, next) => {
  const userId = req.params.uid;

  let transactions;
  try {
    transactions = await Transaction.find({ uid: userId });
  } catch (e) {
    const error = new HttpError("입출금내역을 불러오지 못했습니다.", 500);
    return next(error);
  }

  if (!transactions || transactions.length === 0) {
    return next(
      new HttpError("해당 유저의 입출금내역을 찾지 못했습니다.", 404)
    );
  }

  res.json({
    transactions: transactions.map((t) => t.toObject({ getters: true })),
  });
};

mongoose 함수 find를 이용해 params의 id와 일치하는 Transaction 스키마의 데이터를 모두 찾아온다.

데이터가 여러 건이기 때문에, 요청 전송 현황 확인을 위해 데이터를 불러올 때 map 함수를 사용했다.  

GET 요청이 성공적으로 완료된 모습
오류가 생겼을 때의 화면 (id를 틀리게 입력함)

 

 

🚧 백엔드 → DB  PATCH 요청 보내기

transactions-controller.js

const updateTransaction = async (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(HttpError(errors.array(), 422));
  }

  const { date, category, title, amount, memo } = req.body;
  const transactionId = req.params.tid;

  //id로 해당 입출금 내역 불러오기
  let transaction;
  try {
    transaction = await Transaction.findById(transactionId);
  } catch (e) {
    const error = new HttpError("입출금내역을 불러오지 못했습니다.", 500);
    return next(error);
  }

  //내용 업데이트
  transaction.date = date;
  transaction.category = category;
  transaction.title = title;
  transaction.amount = amount;
  transaction.memo = memo;

  try {
    await transaction.save();
  } catch (e) {
    const error = new HttpError("입출금 내역 수정 실패", 500);
    return next(error);
  }

  res
    .status(200)
    .json({ transaction: transaction.toObject({ getters: true }) });
};

findById 함수로 우선 입출금 내역을 불러오고, 내용 업데이트 후 데이터베이스에 수정된 내용을 save 함수로 저장하는 두 단계를 거친다.

 

 

🚧 백엔드 → DB  DELETE 요청 보내기

transactions-controller.js

const deleteTransaction = async (req, res, next) => {
  const transactionId = req.params.tid;

  let transaction;
  try {
    transaction = await Transaction.findById(transactionId);
  } catch (e) {
    const error = new HttpError("입출금내역을 불러오지 못했습니다.", 500);
    return next(error);
  }

  try {
    await transaction.deleteOne({ id: transactionId });
  } catch (e) {
    const error = new HttpError("입출금내역을 삭제하지 못했습니다.", 500);
    return next(error);
  }

  res.status(200).json({ message: "삭제 완료", transactionId });
};

findById 함수로 id에 해당하는 입출금 내역을 불러오고, 해당 데이터를 deleteOne 함수를 이용해 삭제했다. 

삭제완료 메시지가 정상적으로 확인된다.

 

 

 


참고

 

mongoose 함수

 

[ Node.js ] Mongoose 를 사용해보자!

Mongoose 모듈은 MongoDB 라는 NoSQL 데이터베이스를 Node.js로 사용할 수 있도록 하는 확장 모듈 중 하나 입니다.Mongoose는 데이터를 만들고 관리하기 위해 스키마 \[ Schema ]를 만들고, 그 스키마로 모델을

velog.io

 

 

반응형