일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- Flyway
- SpringBoot
- cloud native
- tasklet
- MSA
- SWAGGER
- Spring Batch
- gradle
- MFA
- openapi3
- AuthenticatoinProvide
- vuejs
- T-OTP
- 리액트
- stopPropogation
- SpringRESTDocs
- Crawling
- axios
- Spring REST Docs
- cheerio
- OpenStack
- Pender
- REACT
- Spring Security
- UsernamePasswordAuthenticationFilter
- JavaScript
- Reduxpender
- Filter
- vue
- preventdefault
- Today
- Total
Miracle Morning, LHWN
2_0. 조회(GET), 삭제(DELETE), 수정(PUT, PATCH) 본문
데이터 조회 (GET)
# 데이터베이스의 데이터를 조회할 때에는 find() 메서드를 사용한다.
exports.list = async (ctx) => {
let books;
try {
books = await Book.find().exec();
} catch (e) {
return ctx.throw(500, e);
}
ctx.body = books;
};
※ let 이나 const 는 scope 가 블록단위이다.
books = await Book.find().exec();
.exec() 함수를 뒤에 붙여주어야 실제로 데이터베이스에 요청이 이루어진다.
이때의 반환 값은 Promise 이기 때문에 await 을 사용할 수 있다.
# 이번에는 여러 옵션을 주어 최근에 생성된 3개의 데이터만 조회해보자. (_id 가 역순으로 정렬되고, 3개만 조회)
exports.list = async (ctx) => {
let books;
try {
books = await Book.find()
.sort({_id: -1})
.limit(3)
.exec();
} catch (e) {
return ctx.throw(500, e);
}
ctx.body = books;
};
.sort({_id: -1}) // _id 의 역순으로 정렬
.limit(3) // 3개만 조회
.exec(); // 데이터를 실제 서버에 요청
# 이번에는 특정 _id 을 가진 데이터를 조회해보자.
exports.get = async (ctx) => {
const { id } = ctx.params;
let book;
try {
book = await Book.findById(id).exec();
} catch (e) {
return ctx.throw(500, e);
}
if(!book) {
ctx.status = 404;
ctx.body = { message: 'book not found' };
return;
}
ctx.body = book;
};
뜯어보자.
const { id } = ctx.params;
요청된 URL 의 파라미터에서 id 값을 읽어온다.
book = await Book.findById(id).exec();
findById () 함수를 이용하여 특정 id 를 가진 데이터를 조회한다.
근데 위 코드처럼 id 를 파라미터로 받을 때에는 사전에 id 값을 검증해주거나, 에러를 처리해주어야 한다.
일단 에러를 처리해보자.
try {
book = await Book.findById(id).exec();
} catch (e) {
if(e.name = 'CastError') {
ctx.status = 400;
return;
}
return ctx.throw(500, e);
}
데이터 삭제 (DELETE)
# 데이터를 삭제하는 함수에는 여러 종류가 있다.
- remove() : 특정 조건을 만족하는 데이터들을 모두 지운다.
- findByIdAndRemove() : id 를 찾아서 지운다.
- findOneAndRemove() : 특정 조건을 만족하는 데이터 하나를 찾아서 지운다.
exports.delete = async (ctx) => {
const { id } = ctx.params;
try {
await Book.findByIdAndRemove(id).exec();
} catch (e) {
if(e.name === 'CastError') {
ctx.status = 400;
return;
}
}
ctx.status = 204; // No Content
};
데이터 수정 (PUT, PATCH)
# PUT 과 PATCH 는 둘 다 데이터를 변경해주지만,
PUT 은 데이터를 통째로 바꾸어주는 메서드이고, → 데이터의 모든 필드를 검증해야 할 것이고, 필드가 존재하지 않으면 새로 만들어줘야 한다.
PATCH 는 주어진 일부 필드만 바꾸어주는 메서드이다.
# PUT 구현해보기
PUT 메서드를 사용할 때 각 필드를 if, 배열, 반복문을 통해 일일이 체크해야 하지만 번거로우니까
이를 편리하게 해주는 'Joi 라이브러리'를 사용해보자.
yarn add joi
const Joi = require('joi');
const { Types: { ObjectId } } = require('mongoose');
// (같은 코딩) cnost ObjectId = require('mongoose').Types.ObjectId;
exports.replace = async (ctx) => {
const { id } = ctx.params;
if(!ObjectId.isValid(id)) {
ctx.status = 400; // Bad Request
return;
}
// 먼저, 검증 할 스키마를 준비해야합니다.
const schema = Joi.object().keys({
title: Joi.string().required(),
authors: Joi.array().items(Joi.object().keys({
name: Joi.string().required(),
email: Joi.string().email().required()
})),
publishedDate: Joi.date().required(),
price: Joi.number().required(),
tags: Joi.array().items((Joi.string()).required())
});
const result = schema.validate(ctx.request.body);
if(result.error) {
ctx.status = 400; // Bad Request
ctx.body = result.error;
return;
}
}
let book;
try {
book = await Book.findByIdAndUpdate(id, ctx.request.body, {
upsert: true,
new: true
});
} catch (e) {
return ctx.throw(500, e);
}
ctx.body = book;
}
또 하나하나 뜯어보자
if(!ObjectId.isValid(id)) {
ctx.status = 400;
return;
}
ObjectId 의 유효성을 검증하는 부분이다.
const schema = Joi.object().keys({
title: Joi.string().required(),
authors: Joi.array().items(Joi.object().keys({
name: Joi.string().required(),
email: Joi.string().email().required()
})),
publishedDate: Joi.date().required(),
price: Joi.number().required(),
tags: Joi.array().items((Joi.string()).required())
});
검증할 Schema 를 정의해주었다. 여기서 각 필드 뒤에 붙은 required() 는 필수 요소라는 의미이다.
또한 email: Joi.string().email().required() 를 통해 이메일도 쉽게 검증할 수 있다.
const result = schema.validate(ctx.request.body);
validate() 를 통해서 request body 를 검증해주는 단계이다.
- schema : 검증의 기준인 스키마
- ctx.request.body : 검증 대상
try {
book = await Book.findByIdAndUpdate(id, ctx.request.body, {
upsert: true,
new: true
});
} catch (e) {
return ctx.throw(500, e);
}
findByIdAndUpdate() 함수의 파라미터는 아래와 같다.
findByIdAndUpdate(아이디, 변경할 값, 설정)
- id : 업데이트할 id 값
- ctx.request.body : 변경할 값
- 설정 : upsert 는 '데이터가 존재하지 않으면 새로 만들어준다.'는 뜻이다.
new 는 이 값을 넣어주어야 반환하는 값이 업데이트된 값이다. 안넣어주면 ctx.body = book 했을 때 업데이트되기 전의 데이터를 보여준다.
# PATCH 구현해보기
exports.update = async (ctx) => {
const { id } = ctx.params;
if(!ObjectId.isValid(id)) {
ctx.status = 400; // Bad Request
return;
}
let book;
try {
book = await Book.findByIdAndUpdate(id, ctx.request.body, {
new: true
});
} catch (e) {
return ctx.throw(500, e);
}
ctx.body = book;
};
PUT 이랑 매우 유사하지만 upsert 옵션을 주지 않는 점이 다르다.
book = await Book.findByIdAndUpdate(id, ctx.request.body, {
new: true
});
findByIdAndUpdate 함수의 upsert 옵션의 기본 값은 false 이기 때문에 해당 옵션을 주지 않는다는 것은
데이터가 존재하지 않으면 생성하지 않는 것이다. = PATCH
출처 : https://backend-intro.vlpt.us/2/06.html
'IT 기술 > [React] Project' 카테고리의 다른 글
3. 프록시(Proxy) 설정으로 CORS 이슈 해결 (0) | 2021.06.01 |
---|---|
[오류] /bin/sh: react-scripts: command not found (0) | 2021.06.01 |
2. Mongoose 를 통한 MongoDB 연동 & 생성 (POST) (0) | 2021.06.01 |
1_0. 이것저것 궁금해서 찾아본 것들 정리 (0) | 2021.06.01 |
1. Node.js express 프레임워크의 session (0) | 2021.05.31 |