블로그용 API 만들기-2
Photo by Nahil Naseer on Unsplash
회원정보를 수정하거나 삭제하는 라우터를 만들어보자
routes/users.js
수정은 업데이트이므로 put
메서드를 사용한다.
삭제는 delete
메서드를 사용한다.
const router = require("express").Router();
const User - require("../models/User");
//수정
router.put("/", async (req, res) => {
try {
} catch {
res.status(500).json(err);
}
});
//삭제
router.delete("/" ...
회원정보 수정
url parameter에 UserId를 넣어 구별한다.
router.put("/:id",
ex)
- 클라이언트가 보낸 요청
api/users/123456
- 서버가 가지고 있는 UserId
{ userId : 123456 , password: 123456abcd ... }
- 사용자 인증 (나중에 jwt 토큰으로 대체)
라우트 파라미터가 가지고 있는 id(정보수정 페이지로 넘어올때 url에 넘긴 id값을 캡쳐해온다)와 (api/users/:id) 요청body안의 UserId와 비교한다.
같다면 업데이트 작업 수행 / 다르다면 401 Unauthorized(인증실패) 메세지 출력
req.params | Express 5.x API Reference
현재 라우트 이름에 따라 바뀌는 객체. 예를들어 라우터 경로가 user/:name 일 경우에 req.params.name으로 사용할 수 있다. 기본값은 빈 객체({})다.
route parameters
요청url에 들어있는 특정 값을 가져오기 위한 url의 한 부분( :id , :name ...등등)이다.
req.params 안에 { 라우트파라미터이름 : 파라미터 값 } 으로 들어간다.Route path: /users/:userId/books/:bookId Request URL: http://localhost:3000/users/34/books/8989 req.params: { "userId": "34", "bookId": "8989" }
Express.js req.params Property - geeks for geeks
if (req.body.userId === req.params.id)
//UPDATE
router.put("/:id", async (req, res) => {
if(req.body.userId === req.params.id) {
try {
} catch {
res.status(500).json(err);
}
} else {
res.status(401).json("잘못된 접근입니다.")
}
});
- 사용자 인증 성공 시 body에 비밀번호가 있다면 암호화
사용자보낸 body에 password값이 있다면 bycrypt로 암호화 후 진행한다.
if(req.body.password) {
const saltRounds = 10;
const salt = await bcrypt.genSalt(saltRounds);
req.body.password = await bcypt.hash(req.body.password, salt);
}
- 업데이트한 값을
findByIdAndUpdate
를 이용해$set
으로 넣어준다.
findByIdAndUpdate
: document의 _id를 기준으로 MongoDBfindAndModify
를 수행한다.
findAndModify - MongoDB
findByIdAndUpdate - mongoose
$set - mongoose
Example:
Model.findByIdAndUpdate(id, { name: 'jason bourne' }, options, callback)
// is sent as
Model.findByIdAndUpdate(id, { $set: { name: 'jason bourne' }}, options, callback)
This helps prevent accidentally overwriting your document with { name: 'jason bourne' }.
const router = require("express").Router();
const e = require("express");
const User = require("../models/User");
const bcrypt = require("bcrypt");
//UPDATE
router.put("/:id", async (req, res) => {
if(req.body.userId === req.params.id) {
if(req.body.password) {
const saltRounds = 10;
const salt = await bcrypt.genSalt(saltRounds)
req.body.password = await bcrypt.hash(req.body.password, salt);
}
try {
const updatedUser = await User.findByIdAndUpdate(req.param.id, {
$set: req.body,
});
res.status(200).json(updatedUser);
} catch {
res.status(500).json(err);
}
} else {
res.status(401).json("계정 소유자만 수정 가능합니다.")
}
});
module.exports = router;
index.js에서 라우터를 불러온다.
const userRoute = require("./routes/users");
app.use("/api/user", userRoute");
이제 MongoDB에 저장되있는 유저 아이디로 요청해보자
- body에 담긴 userId가 라우트파라미터와 일치하지 않을 경우
- 일치하는 경우 (200)
여기서 응답객체가 업데이트되지 않은 상태로 보여지는데 MongoDB를 확인해보면 업데이트 되어있다.
다시 users.js route파일로 돌아가서 updatedUser
의 findByIdAndUpdate
에 옵션으로 {new: true}
를 추가해준다.
findOneAndUpdate()는 업데이트가 적용되기 전 document를 반환하지만, new: true로 설정하면 엄데이트 된 후의 객체를 반환한다.
const updatedUser = Users.findByIdAndUpdate(req.params, {
$set: req.body
}, {new = true});
다시 요청을 시도해보자
이제 업데이트된 후의 데이터를 반환한다.
계정삭제
//DELETE
router.delete('/:id', async (req, res) => {
if(req.body.userId === req.params.id) {
try {
await User.findByIdAndDelete(req.params.id);
res.status(200).json("계정이 삭제되었습니다.")
} catch (err) {
res.status(500).json(err);
} else {
res.status(401).json("본인 소유 계정만 삭제 가능합니다.")
}
})
사용자 정보 수정과 마찬가지로 유저아이디를 비교한 후
findByIdAndDelete
를 사용해 파라미터에 명시된 계정id를 db에서 찾아 삭제한다.
단, 이 과정에서 계정이 삭제되면 계정사용자가 업로드한 게시물도 지워져야 한다.
User.findById
로 id를 검색했을때 계정이 있다면 작업을 계속하고 없는 경우에는 사용자를 찾을 수 없다는 메시지(404)를 출력하는 조건문을 추가한다.
- 통신은 항상 await로 실행한다 -> 언제 응답할 지 모르니까
//DELETE
router.delete('/:id', async (req, res) => {
if(req.body.userId === req.params.id) {
if(await User.findById(req.params.id)) {
try {
await User.findByIdAndDelete(req.params.id);
res.status(200).json("계정이 삭제되었습니다.")
} catch (err) {
res.status(500).json(err);
}
} else {
res.status(404).json("사용자를 찾을 수 없습니다.")
}
} else {
res.status(401).json("본인 소유 계정만 삭제 가능합니다.")
}
})
이제 포스트 정보를 가져오기 위해 포스트모델을 불러온다.
const Post = require("../models/Post");
Post모델을 기준으로 deleteMany
를 사용해 DB안에서 username이 User.username과 같은 모든 document들을 삭제하는 코드를 추가한다.
포스트맨에서 삭제요청을 테스트한다.
DB내에서도 사라졌다.
유저 정보 불러오기
//GET USER
router.get("/:id", async (req, res) => {
try {
const user = await User.findById(req.params.id);
const {password, ...others} = user._doc;
res.status(200).json(others);
} catch(err) {
res.status(500).json(err);
}
})
데이터를 수정하지 않고 열람만 할 경우get
메서드를 사용해 불러온다.
findById
로 파라미터의 id값과 일치하는 document를 user
라는 변수에 저장하고
로그인 라우터를 만들때처럼 디스트럭처링으로 mongoose document class를 받아오고 _doc
프로퍼티를 이용해서 비밀번호만 빼고 사용자 정보를 보여줄 수 있다.
패스워드를 제외한 나머지 정보가 정상적으로 들어온다.
Author And Source
이 문제에 관하여(블로그용 API 만들기-2), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@mhnormal/블로그용-API-만들기-2저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)