2. Express로 TODO

jonyChoiGenius·2023년 12월 13일
0

NEXT JS 13 투두앱

목록 보기
2/4

1. Node.JS로 TODO 를 express를 통해 작업해보자.

Express는 Node.js의 서버 프레임워크이다.
아래와 같이 터미널에서 실행하여 Express 모듈을 설치해야 한다.

npm init -y
npm install express

한편 앞서 헤더를 통해 해결했던 CORS 이슈를 cors 모듈을 이용한 미들웨어로 해결할 수 있다.

npm install cors

서버 실행하기

app.js 파일을 만들어 아래와 같이 작성한다.

const express = require("express");
const cors = require("cors");
const app = express();

app.use(cors()); // app.use(경로, 미들웨어 함수) 혹은 app.use(미들웨어 함수)는 요청에 대해 핸들링한다.
// 미들웨어 함수는 req, res, next를 응답으로 받아, next()를 호출하는 함수이다.

app.get("/", (req, res) => {
  res.json({ url: "암것두 없다" }); //res.json은 객체를 파라미터로 받는다. 받은 객체를 JSON 형식으로 변환하고, 헤더에 application/json을 자동으로 추가해준다.
});

app.listen(8080, () => {
  console.log("8080번 포트에서 익스프레스 실행");
});
  1. app.use를 통해 요청을 미들웨어 함수로 핸들링할 수 있다. req를 받아, res를 수정한 후, next()를 통해 다음 구문을 실행하는 방식이다. app.use(cors())는 자동으로 헤더에 cros를 핸들링하는 값을 추가해준다.

  2. app.get(라우트, 리퀘스트 핸들러)와 같은 방식으로 요청을 간단하게 처리할 수 있다.

여기에 노드JS에서 chunk를 파싱하기 위해 했던

        req
          .on("data", (chunk) => {
            requestBody += chunk;
          })
          .on("end", () => {
            const user = JSON.parse(requestBody);
          }

위의 작업을 미들웨어를 통해 아래와 같이 단순화할 수 있다.

app.use(express.json());

JSON 파일을 쓰고 읽기

앞선 node js 예제에서는 자바스크립트 배열을 사용했지만, 이번엔 JSON 파일을 사용해보자.
touch data.json로 JSON 파일을 만들고,
아래와 같이 get, post 요청을 만들었다.

이때 파일의 주소를 가져오는 데에는 3가지가 사용될 수 있다.
process.cwd() : app.js가 실행되고 있는 경로를 반환한다.
__dirname : 현재 파일이 실행되고 있는 경로를 반환한다.
__filename : 현재 실행중인 파일의 경로를 반환한다.
가령 아래와 같다.

process.cwd() : c:\Users\jonghyun\Desktop\node-js-todo\express-server
__dirname : c:\Users\jonghyun\Desktop\node-js-todo\express-server\routes\user
__filename : c:\Users\jonghyun\Desktop\node-js-todo\express-server\routes\user\[id].js

이렇게 받은 path는 윈도우에서는 역슬래시, 리눅스, 맥, 자바스크립트에서는 슬래시를 사용한다. 경로를 파싱하기 위해서는 path라이브러리를 사용할 수 있다.

const fs = require("fs");
const path = require("path");

app
  .route("/user")
  .get((req, res) => {
    fs.readFile(path.join(__dirname, "data.json"), "utf8", (err, data) => {
      const jsonData = JSON.parse(data);
      res.json(jsonData);
    });
  })
  .post((req, res) => {
    // 기존 데이터 읽기
    fs.readFile(path.join(__dirname, "data.json"), "utf-8", (err, data) => {
      const jsonData = JSON.parse(data);
      jsonData.push({ id: jsonData.at(-1).id + 1, ...req.body });

      // 업데이트된 데이터 파일에 쓰기
      fs.writeFile(
        path.join(__dirname, "data.json"),
        JSON.stringify(jsonData, null, 2),
        "utf-8",
        (err) => {
          res.json(jsonData);
        }
      );
    });
  });

라우터 모듈

위와 같은 app.route와 달리, express.Router()를 이용하여 라우터 모듈을 만들 수 있다.

routes\user[id].js 파일을 만든 후,
아래와 같이 user/:id를 받는 로직을 만들었다.

이때 :id로 받은 params는, req.params.id로 접근할 수 있다.

const express = require("express");
const fs = require("fs");
const path = require("path");

const router = express.Router();

router.get("/:id", (req, res) => {
  const userId = Number(req.params.id);

  fs.readFile(path.join(__dirname, "../../data.json"), (err, data) => {
    console.log(userId);
    console.log(process.cwd());
    console.log(__dirname);
    console.log(__filename);
    const jsonData = JSON.parse(data);
    const user = jsonData.find((user) => user.id === userId);
    res.json(user);
  });
});

router.patch("/:id", (req, res) => {
  const userId = Number(req.params.id);
  fs.readFile(path.join(__dirname, "../../data.json"), (err, data) => {
    const jsonData = JSON.parse(data);
    const user = jsonData.find((user) => user.id === userId);
    Object.entries(req.body).forEach((entry) => {
      const [key, value] = entry;
      user[key] = value;
    });

    fs.writeFile(
      path.join(__dirname, "../../data.json"),
      JSON.stringify(jsonData, null, 2),
      "utf-8",
      (err) => {
        res.json(user);
      }
    );
  });
});

module.exports = router;

이렇게 export한 router는 app.use에서 추가할 수 있다.

// app.js
const userRouter = require("./routes/user/[id]");
app.use("/user", userRouter);

전체 코드
app.js

const express = require("express");
const fs = require("fs");
const userRouter = require("./routes/user/[id]");
const path = require("path");
const cors = require("cors");
const app = express();

app.use(cors()); // app.use(경로, 미들웨어 함수) 혹은 app.use(미들웨어 함수)는 요청에 대해 핸들링한다.
// 미들웨어 함수는 req, res, next를 응답으로 받아, next()를 호출하는 함수이다.
app.use((req, res, next) => {
  console.log(req.url);
  next();
});

app.use(express.json());
app.use("/user", userRouter);

app.get("/", (req, res) => {
  res.json({ url: "암것두 없다" }); //res.json은 객체를 파라미터로 받는다. 받은 객체를 JSON 형식으로 변환하고, 헤더에 application/json을 자동으로 추가해준다.
});

app
  .route("/user")
  .get((req, res) => {
    fs.readFile(path.join(__dirname, "data.json"), "utf8", (err, data) => {
      const jsonData = JSON.parse(data);
      res.json(jsonData);
    });
  })
  .post((req, res) => {
    // 기존 데이터 읽기
    fs.readFile(path.join(__dirname, "data.json"), "utf-8", (err, data) => {
      const jsonData = JSON.parse(data);
      jsonData.push({ id: jsonData.at(-1).id + 1, ...req.body });

      // 업데이트된 데이터 파일에 쓰기
      fs.writeFile(
        path.join(__dirname, "data.json"),
        JSON.stringify(jsonData, null, 2),
        "utf-8",
        (err) => {
          res.json(jsonData);
        }
      );
    });
  });

app.listen(8084, () => {
  console.log("8084번 포트에서 익스프레스 실행");
});

routes\user[id].js

const express = require("express");
const fs = require("fs");
const path = require("path");

const router = express.Router();

router.get("/:id", (req, res) => {
  const userId = Number(req.params.id);

  fs.readFile(path.join(__dirname, "../../data.json"), (err, data) => {
    console.log(userId);
    console.log(process.cwd());
    console.log(__dirname);
    console.log(__filename);
    const jsonData = JSON.parse(data);
    const user = jsonData.find((user) => user.id === userId);
    res.json(user);
  });
});

router.patch("/:id", (req, res) => {
  const userId = Number(req.params.id);
  fs.readFile(path.join(__dirname, "../../data.json"), (err, data) => {
    const jsonData = JSON.parse(data);
    const user = jsonData.find((user) => user.id === userId);
    Object.entries(req.body).forEach((entry) => {
      const [key, value] = entry;
      user[key] = value;
    });

    fs.writeFile(
      path.join(__dirname, "../../data.json"),
      JSON.stringify(jsonData, null, 2),
      "utf-8",
      (err) => {
        res.json(user);
      }
    );
  });
});

module.exports = router;
profile
천재가 되어버린 박제를 아시오?

0개의 댓글

관련 채용 정보