코딩캠프/내일배움캠프

[ TIL ] 12.19(월) 26일차

고랑E 2022. 12. 19. 21:00
728x90

이번주는 노드 숙련주차.. 입문도 어려웠고 이해 못하고 이번주로 넘어왔다

 

Node.js - JavaScript를 브라우저 없이 단독으로 실행할 수 있는 하나의 플랫폼이다.

npm - Node.js에서 오픈소스 라이브러리를 쉽게 사용하기 위해 개발된 패키지 관리자

express - 쉽게 서버 프로그램을 구성할 수 있게 만들어진 오픈소스 라이브러리

HTTP - 데이터를 주고 받을 때 사용되는 통신 규약

웹 브라우저 - HTML로 이루어진 데이터를 읽어서 화면에 보여주는 역할

쿠키 - 사용자의 상태를 저장

세션 - 기본적으로는 쿠키를 사용하지만 세션 id만 쿠키로 저장하고 데이터들은 서버에 저장한다.

 

 

할 일 메모 사이트 - API  서버 준비하기

 

app.js

const express = require("express");

const app = express();
const router = express.Router();

router.get("/", (req, res) => {
  res.send("Hi!");
});
app.use("/api", express.json(), router);

app.listen(8080, () => {
  console.log("서버가 켜졌어요!");
});
app.use("/api", express.json(), router);

app.use 는 미들웨어를 사용하게 해주는 코드

http://localhost:8080/api 경로로 접근하는 경우에만 json 미들웨어를 거친 뒤 router로 연결

 

이번 숙련주차에서는 프론트엔드 코드를 제공해줘서

https://s3.ap-northeast-2.amazonaws.com/materials.spartacodingclub.kr/nodejs_advanced/week01/todo-web-week1.zip

위 파일을 다운로드 받아 압축 푼 파일들을 assets 폴더 안에 넣어준다.

 

추가된 assets 폴더 안에 파일들을 미들웨어를 추가

 

app.js

const express = require("express");

const todosRouter = require("./routes/todos.router.js");

const app = express();

app.use("/api", express.json(), todosRouter);
app.use(express.static("./assets"));

app.listen(8080, () => {
  console.log("서버가 켜졌어요!");
});

 

routes 폴더 ,  todos.router.js 파일 생성

// routes/todos.router.js

const express = require("express");
const router = express.Router();

router.get("/", (req, res) => {
  res.send("Hi!");
});

module.exports = router;

 

app.use(express.static("./assets"));

express.static 함수는 app.js 파일 기준으로 입력하고

해당 경로에 있는 파일을 아무런 가공 없이 그대로 전달해주는 미들웨어.

 

 

MongoDB 연결 준비

 

models 폴더, index.js 파일 생성

// models/index.js

const mongoose = require("mongoose");

// localhost의 27017 포트 번호로 MongoDB와 연결합니다.
// Database Name은 todo-demo 입니다.
mongoose.connect("mongodb://localhost:27017/todo-demo", {
  useNewUrlParser: true,
  useUnifiedTopology: true,
})
  .then(value => console.log("MongoDB 연결에 성공하였습니다."))
  .catch(reason => console.log("MongoDB 연결에 실패하였습니다."))


const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));

module.exports = db;

 

추가 후 node app.js 실행 하고 좀 기다리면 MongoDB 연결에 실패하였습니다. 문구가 뜬다

 

models/index.js 에서 7줄의

 

localhost 를 127.0.0.1 로 변경하면 오류 없이 잘 실행된다.

mongodb://localhost:27017/todo-demo


mongodb://127.0.0.1:27017/todo-demo

 

할 일 메모 사이트 - API  구현하기

Todo 모델 작성

models 폴더안에 todo.js 파일 생성

// models/todo.js

const mongoose = require("mongoose");

const TodoSchema = new mongoose.Schema({
  value: String,
  doneAt: Date,
  order: Number
});
TodoSchema.virtual("todoId").get(function () {
  return this._id.toHexString();
});
TodoSchema.set("toJSON", {
  virtuals: true,
});
module.exports = mongoose.model("Todo", TodoSchema);

 

Schema.virtual

mongoose 라이브러리에서는 몽고DB에 특정컬럼이 존재하지 않지만

데이터를 조회할때 가상의 컬럼을 추가해서 쉽게 사용할 수 있게 도와준다.

 

routes/todos.router.js 수정

 

order라는 숫자 값을 같이 저장하는데

이 값은 Todo 데이터들의 순서를 가지는 값

order가 높을 수록 데이터가 상단에 위치하고

추가 할때 마다 order 값을 +1 해준다.

// routes/todos.router.js
const express = require("express");
const Todo = require("../models/todo");

const router = express.Router();

router.get("/", (req, res) => {
  res.send("Hi!");
});

router.post("/todos", async (req, res) => {
  const { value } = req.body;
  const maxOrderByUserId = await Todo.findOne().sort("-order").exec();

  const order = maxOrderByUserId ? maxOrderByUserId.order + 1 : 1;
  const todo = new Todo({ value, order });
  await todo.save();
  res.send({ todo });
});

module.exports = router;

 

할 일 목록 가져오는 API

목록을 가져오는데 order 라는 값을 기준으로 내림차순해서 가져온다

// routes/todos.router.js

router.get("/todos", async (req, res) => {
  const todos = await Todo.find().sort("-order").exec();

  res.send({ todos });
});

sort() 를 사용해 조회를 한 데이터를 정렬 할 수 있다.

-가 있으면 내림차순 / 없으면 오름차순

exec() 는 완료

 

할 일 순서 변경하는 API

// routes/todos.router.js

router.patch("/todos/:todoId", async (req, res) => {
  const { todoId } = req.params;
  const { order } = req.body;

  const currentTodo = await Todo.findById(todoId);
  if (!currentTodo) {
    throw new Error("존재하지 않는 todo 데이터입니다.");
  }

  if (order) {
    const targetTodo = await Todo.findOne({ order }).exec();
    if (targetTodo) {
      targetTodo.order = currentTodo.order;
      await targetTodo.save();
    }
    currentTodo.order = order;
  }

  await currentTodo.save();

  res.send({});
});