본문 바로가기
웹 프로젝트/👨‍👨‍👧‍👧소셜 가계부

[React/Node.js/Express/MongoDB] 소셜 가계부 프로젝트 구현 일지: 백엔드 구현하기 (입출금 내역 - GET 요청 보내기)

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

기본 라우터 추가하기(GET 요청 사용)

app.js

const express = require("express");
const bodyParser = require("body-parser");

const app = express();

const transactionsRouter = require("./routes/transactions-routes");

app.use(transactionsRouter);

app.listen(5000);

 

* app.use()

지정된 경로에 존재하는 미들웨어 함수를 마운트한다. (요청된 경로와 일치하는 미들웨어 함수가 실행된다.)

 

Express 4.x - API 참조

Express 4.x API express() Creates an Express application. The express() function is a top-level function exported by the express module. var express = require('express') var app = express() Methods express.json([options]) This middleware is available in Ex

expressjs.com

 

routes > transactions-routes.js

const express = require("express");

const router = express.Router(); //특수 객체 생성

//라우트에 요청이 도달하면 실행되어야 하는 함수
router.get("/", (req, res, next) => {
  console.log("Ger request");
  res.json({ message: "작동됨" }); //원하는 객체 전달
});

// router 상수를 내보내기
module.exports = router;

 

http://localhost:5000/ 접속 시 아래와 같이 뜨면 정상적으로 GET 요청이 진행되고 있다는 뜻이다.

입출금 내역 id별 라우터 추가하기(GET 요청 사용)

app.js

const express = require("express");
const bodyParser = require("body-parser");

const app = express();

const transactionsRouter = require("./routes/transactions-routes");

// 경로가 "/api/transactions"로 시작된다면 transactionsRouter 실행
app.use("/api/transactions", transactionsRouter);

app.listen(5000);

 

routes > transactions-routes.js

const express = require("express");

const router = express.Router(); //특수 객체 생성

const DUMMY_TRANSACTION = [
  {
    tid: "1",
    date: 1705029633942,
    category: "교통/차량",
    description: "버스비",
    amount: -4000,
    transaction_type: "지출",
    memo: "버스비",
  },
  {
    tid: "2",
    date: 1705129633942,
    category: "용돈",
    description: "용돈",
    amount: 12000,
    transaction_type: "수입",
    memo: "",
  },
  {
    tid: "3",
    date: 1705229633942,
    category: "문화비",
    description: "서적구매",
    amount: -25000,
    transaction_type: "지출",
    memo: "컴퓨터공학입문서 구입",
  },
];

//라우트에 요청이 도달하면 실행되어야 하는 함수
router.get("/:tid", (req, res, next) => {
  const transactionId = req.params.tid; // type: string

  const transaction = DUMMY_TRANSACTION.find((t) => {
    return t.tid === transactionId;
  });
  res.json({ transaction: transaction }); //원하는 객체 전달
});

// router 상수를 내보내기
module.exports = router;

 

http://localhost:5000/api/transactions/3

위 api 주소로 접속 시, 아래와 같이 전송한 api 정보가 뜬다.

에러 핸들링

app.js

const express = require("express");

const app = express();

const transactionsRouter = require("./routes/transactions-routes");

// 경로가 "/api/transactions"로 시작된다면 transactionsRouter 실행
app.use("/api/transactions", transactionsRouter);

//매개변수 4개: 오류 처리 미들웨어 함수
//앞의 미들웨어 함수에서 오류가 발생했을 때만 실행된다.
app.use((error, req, res, next) => {
  //응답이 이미 전송되었는지 확인
  if (res.headerSent) {
    return next(error);
  }

  //응답이 전송되지 않은 경우
  //상태 코드가 정의된 경우에는 코드를, 아닌 경우에는
  //서버에 어떤 문제가 있음을 알려주는 기본 상태코드 500이 반환되도록 함
  res.status(error.code || 500);
  res.json({ message: error.message || "정의되지 않은 에러 발생" });
});

app.listen(5000);

 

routes > transaction-routes.js

const express = require("express");

const router = express.Router(); //특수 객체 생성

const DUMMY_TRANSACTION = [
  ...
];

//라우트에 요청이 도달하면 실행되어야 하는 함수
router.get("/:tid", (req, res, next) => {
  const transactionId = req.params.tid; // type: string

  const transaction = DUMMY_TRANSACTION.find((t) => {
    return t.tid === transactionId;
  });

  // 입출금 내역 id 찾지 못한 경우 에러 핸들링
  // 비동기 코드가 존재하는 경우 next에 오류를 전달하는 방식으로 에러 처리
  if (!transaction) {
    const error = new Error("해당 ID에 대한 입출금내역을 찾지 못했습니다.");
    error.code = 404; //오류 상태
    throw error;
  }

  res.json({ transaction: transaction }); //원하는 객체 전달
});

// router 상수를 내보내기
module.exports = router;

 

http://localhost:5000/api/transactions/39

위 api 주소로 접속 시, 39번 tid를 가진 입출금 내역은 없기 때문에 아래와 같이 에러 정보가 출력된다.

 

 

routes 파일과 controller 파일 분리 (코드 모듈화)

코드의 구조화와 유지보수성을 높이기 위한 코드 모듈화를 진행하였다.

 

`기존 routes 파일`

routes > transactions-routes.js

const express = require("express");

const router = express.Router(); //특수 객체 생성

const DUMMY_TRANSACTION = [
  ...
];

//라우트에 요청이 도달하면 실행되어야 하는 함수
router.get("/:tid", (req, res, next) => {
  const transactionId = req.params.tid; // type: string

  const transaction = DUMMY_TRANSACTION.find((t) => {
    return t.tid === transactionId;
  });

  // 입출금 내역 id 찾지 못한 경우 에러 핸들링
  // 비동기 코드가 존재하는 경우 next에 오류를 전달하는 방식으로 에러 처리
  if (!transaction) {
    const error = new Error("해당 ID에 대한 입출금내역을 찾지 못했습니다.");
    error.code = 404; //오류 상태
    throw error;
  }

  res.json({ transaction: transaction }); //원하는 객체 전달
});

// router 상수를 내보내기
module.exports = router;

routes 파일에서 컨트롤러 코드를 따로 분리해 주었다.

routes는 URL의 경로를, controllers는 해당 경로의 비즈니스 로직을 다룬다.

 

👇

 

`파일 분리를 마친 후 routes 파일`

routes > transactions-routes.js

const express = require("express");

const router = express.Router(); //특수 객체 생성

const transactionsControllers = require("../controllers/transactions-controller");

//라우트에 요청이 도달하면 실행되는 함수
router.get("/:tid", transactionsControllers.getTransactionById);

module.exports = router;

 

`파일 분리를 마친 후 controller 파일`

controllers > transactions-controller.js

const DUMMY_TRANSACTION = [
  {
    tid: "t1",
    uid: "u1",
    date: 1705029633942,
    category: "교통/차량",
    description: "버스비",
    amount: -4000,
    transaction_type: "지출",
    memo: "버스비",
  },
  {
    tid: "t2",
    uid: "u2",
    date: 1705129633942,
    category: "용돈",
    description: "용돈",
    amount: 12000,
    transaction_type: "수입",
    memo: "",
  },
  {
    tid: "t3",
    uid: "u1",
    date: 1705229633942,
    category: "문화비",
    description: "서적구매",
    amount: -25000,
    transaction_type: "지출",
    memo: "컴퓨터공학입문서 구입",
  },
  {
    tid: "t4",
    uid: "u2",
    date: 1709329633942,
    category: "식비",
    description: "외식비",
    amount: -52000,
    transaction_type: "지출",
    memo: "외식",
  },
];

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

  const transaction = DUMMY_TRANSACTION.find((t) => {
    return t.tid === transactionId;
  });

  // 에러 핸들링
  if (!transaction) {
    const error = new Error("해당 ID에 대한 입출금내역을 찾지 못했습니다.");
    error.code = 404; //오류 상태
    throw error;
  }

  res.json({ transaction: transaction });
};

exports.getTransactionById = getTransactionById;

 

 

유저 id별 입출금 내역 GET 요청

입출금 id별 입출금을 가져올 때와 동일한 방식으로 유저별 입출금 내역 가져오기를 진행한다.

 

transactions-controllers.js

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

  const transactions = DUMMY_TRANSACTION.filter((u) => {
    return u.uid === userId;
  });

  if (!transactions || transactions.length === 0) {
    const error = new Error(
      "해당 유저의 입출금내역을 찾지 못했습니다."
    );
    error.code = 404;
    throw error;
  }

  res.json({ transactions });
};

exports.getTransactionByUserId = getTransactionByUserId;

 

transactions-routes.js

router.get("/user/:uid", transactionsControllers.getTransactionsByUserId);

 

http://localhost:5000/api/transactions/user/u1 주소로 접속 시, u1이라는 id를 가진 유저의 가계부 목록을 배열 형태로 불러온다.

반응형