본문 바로가기
타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js)/TIL

웹풀사이클 17일차 - 핸들러, forEach/find, 예외처리(status), router, 유튜브 회원 api 만들기

by 슈크림 붕어빵 2023. 12. 15.

핸들러란?

http request가 날아오면 자동으로 호출되는 메소드를 의미한다.

node에서는 콜백함수로, app.httpmethod(path,handler) 중 handler 부분이다.

예를 들면 다음에서 function부분!

 
app.get("/youtubers", function (req, res) { });
 

 

 

find와 forEach

find를 사용하면 forEach보다 훨씬 간단한 코드로 배열에서 객체를 찾을 수 있다.

다음의 fruit 배열이 있을 때, 입력받은 id와 같은 id의 객체를 찾는 코드를 배교해보자

const fruits = [
  { id: 1, name: "apple" },
  { id: 2, name: "orange" },
  { id: 3, name: "blueberry" },
  { id: 4, name: "strawberry" },
];
  • forEach
let fruit;
fruits.forEach(function (value) {
   if (value.id == id) {
     fruit = value;
   }
});
  • find
let fruit = fruits.find((f) => f.id == id);

 

예외처리 status

2xx - 성공

1. 등록 성공 - post, 201

  • ex - 등록 성공 (201)
res.status(201).json(`${req.body.channelName}님 유튜브 개설을 축하합니다.`);

 

4xx - 클라이언트의 잘못

  • 요청의 문법이 잘못되었거나 요청을 처리할 수 없다.
  • ex - 유효하지 않는 url (404)

1. 찾는 리소스가 없음 - get, 404

app.get("/fruits/:id", (req, res) => {
  let { id } = req.params;
  id = parseInt(id);

  let fruit;
  fruit = fruits.find((f) => f.id == id);

  if (fruit) {
    res.json(fruit);
  } else {
    res.status(404).json({ message: `해당 id ${id}의 과일이 없습니다.` });
  }
});
  • 예외처리를 하는 if else문이 없이 바로 보내는 경우, 해당 id의 객체가 없더라도 fruit이 빈 상태로 넘어간다. 이런 경우 명확히 표시해 줄 필요가 있으므로 status로 404를 보내줘 해당 id의 과일이 없음을 알린다.
  • res.status(404)
  • 클라이언트와 정확한 소통을 위해 상태코드 사용

2. 요청한 연산을 할 때 필요한 req가 덜 온 경우 - post, 400

app.post("/youtubers", (req, res) => {
  if(req.body.channelName&&req.body.description){
    console.log(req.body);
    db.set(id++, req.body);
    res.status(201).json(`${req.body.channelName}님 유튜브 개설을 축하합니다.`);
  }
  else{
    res.status(400).json({
      message:"채널명과 설명은 필수로 입력해야합니다."
    })
  }
});

 

 

5xx: 서버의 잘못

  • 서버가 명백히 유효한 요청에 대해 충족을 실패했다.
  • ex - 서버가 죽었을 때 (500)

== vs ===

console.log(1 == "1");
console.log(1 === "1");

결과

 
true
false
 
  • ===은 자료형과 값 모두 비교
  • ==은 자료형과 관계없이 값만 비교

 

유튜브를 운영하려면 필요한 기능

 

회원

  • 로그인
  • 회원가입
  • 회원 탈퇴

 

채널

  • 채널 생성
  • 채널 수정
  • 채널 삭제

로그인 페이지 : 로그인 api

회원가입 페이지: 회원가입 api

마이페이지: 회원정보 조회api, 회원탈퇴 api

 

회원 api설계

 

1. 로그인 => post, /login

//로그인
app.post("/login", (req, res) => {
  let { id, pw } = req.body;
  let user;
  db.forEach((value) => {
    if (value.id == id) {
      user = value;
    }
  });
  console.log(user);
  if (user) {
    if (user.pw == pw)
      res.json({
        message: `${user.id}님 환영합니다.`,
      });
    else {
      res.json({
        message: `비밀번호가 일치하지 않습니다.`,
      });
    }
  } else {
    res.json({
      message: `존재하지 않는 아이디입니다.`,
    });
  }
});
  • req: body(id,pwd)
  • res: 이름님 환영합니다.
  • 홈으로 돌아가기

 

2. 회원가입 => post, /join

//회원가입
app.post("/join", (req, res) => {
  let { id, pw, name } = req.body;
  let user;
  if (id && pw && name) {
    db.forEach((value) => {
      if (value.id === id) {
        user = value;
      }
    });
    if (user) {
      res.status(400).json({
        message: `이미 존재하는 id입니다.`,
      });
    } else {
      db.set(index++, req.body);
      res.status(201).json({
        message: `${id}님 환영합니다.`,
      });
    }
  } else {
    res.status(400).json({
      message: `id, 비밀번호, 이름은 필수 항목입니다.`,
    });
  }
});
  • req: body (id, pwd, name)
  • res: 이름님 환영합니다.
  • 로그인페이지로 

3. 개별 회원정보 조회 => get, /users:id

app.get("/users/:id", (req, res) => {
  let { id } = req.params;
  id = parseInt(id);
  let user = db.get(id);
  if (user) {
    res.status(200).json({
      id: user.id,
      name: user.name,
    });
  } else {
    res.status(404).json({
      message: `존재하지 않는 아이디입니다.`,
    });
  }
});
  • req: params.id
  • res: id, name

 

4. 회원 탈퇴 => delete, /users/:id

//회원 개별 탈퇴
app.delete("/users/:id", (req, res) => {
  let { id } = req.params;
  id = parseInt(id);
  if (db.has(id)) {
    let userName = db.get(id).name;
    db.delete(id);
    res.status(200).json({
      message: `${userName}님 탈퇴되었습니다.`,
    });
  } else {
    res.status(404).json({
      message: `존재하지 않는 아이디입니다.`,
    });
  }
});
  • req: params.id
  • res: 님 다음에 또 만나요.
  • 홈으로 돌아가기

app.route 사용하기

개별 회원 조회와 개별 회원 삭제는 url path가 같은 것을 확인할 수 있다. 이를 한번에 묶어줄 수 있는 것이 route이다.

다음과 같이 app.route('주소').get([핸들러]).delete([핸들러])와 같이 사용할 수 있다.

app
  .route("/users/:id")
  .get((req, res) => {
    let { id } = req.params;
    id = parseInt(id);
    let user = db.get(id);
    if (user) {
      res.status(200).json({
        id: user.id,
        name: user.name,
      });
    } else {
      res.status(404).json({
        message: `존재하지 않는 아이디입니다.`,
      });
    }
  })
  .delete((req, res) => {
    let { id } = req.params;
    id = parseInt(id);
    if (db.has(id)) {
      let userName = db.get(id).name;
      db.delete(id);
      res.status(200).json({
        message: `${userName}님 탈퇴되었습니다.`,
      });
    } else {
      res.status(404).json({
        message: `존재하지 않는 아이디입니다.`,
      });
    }
  });