8-3. 포스트 작성 API 구현하기
포스트 작성 모델 메소드 생성
이번엔 포스트 작성 API 를 구현해보겠습니다. 우선, Posts 모델에 write 라는 스태틱 함수를 만들어주세요.
src/models/post
(...)
Post.statics.write = function({count, username, content}) {
const post = new this({
count, username, content
});
return post.save();
};
module.exports = mongoose.model('Post', Post);
이 메소드는 count, username, content 값을 받습니다. 여기서 count 는 이번에 작성되는 포스트가 유저가 몇번쨰로 작성했는지에 대한 숫자가 들어가게 됩니다. 포스트를 작성 할 떄마다 Account 모델의 thoughtCount 가 1씩 올라가게 되며, 그 값이 이 메소드의 count 값으로 설정이 되는거죠.
포스트 작성 로직 미리 확인하기
포스트 작성에 대한 로직은 어떻게 이뤄져있는지, 확인을 해볼까요?
- 유저 검증
- 유저의 thoughtCount 가져오기, 1 더하기
- 요청 데이터 스키마 검증하기
- 포스트 write 메소드 호출
- 요청자에게 포스트 정보반환
- 소켓을 통하여 접속중인 유저에게 실시간 포스트 정보 전송
여기서, 5번의 경우엔 나중에 구현을 하고, 이번 섹션에서는 5번까지만 구현을 하겠습니다.
Account 모델 increaseThoughtCount 인스턴스 메소드 만들기
Account 의 thoughtCount 에 1을 더해주는 increaseThoughtCount 메소드를 만들어보세요
src/models/account.js
(...)
Account.methods.increaseThoughtCount = function() {
this.thoughtCount++;
return this.save();
};
module.exports = mongoose.model('Account', Account);
포스트 API 요청 처리하기
그럼, 위 로직에 따라 코드를 입력해봅시다.
src/api/posts
const Account = require('models/account');
const Post = require('models/post');
const Joi = require('joi');
exports.write = async (ctx) => {
/* 유저 검증하기 */
const { user } = ctx.request;
if(!user) {
// 비로그인 에러
ctx.status = 403;
ctx.body = { message: ' not logged in' };
return;
}
/* 유저의 thoughtCount 가져오기 */
let account;
try {
account = await Account.findById(user._id).exec();
} catch (e) {
ctx.throw(500, e);
}
if(!account) {
ctx.status = 403; // Forbidden
return;
}
const count = account.thoughtCount + 1;
/* 요청 데이터 스키마 검증하기 */
const schema = Joi.object().keys({
content: Joi.string().min(5).max(1000).required() // 5~1000 자
});
const result = Joi.validate(ctx.request.body, schema);
if(result.error) {
// 스키마 오류 발생
ctx.status = 400; // Bad request
return;
}
const { content } = ctx.request.body;
/* 포스트 write 메소드 호출 */
let post;
try {
post = await Post.write({
count,
username: user.profile.username,
content
});
await account.increaseThoughtCount();
} catch (e) {
ctx.throw(500, e);
}
/* 포스트 정보 반환 */
ctx.body = post;
/* TODO: 소켓을 통하여 접속중인 유저에게 실시간 포스트 정보 전송 */
};
(...)
이제 포스트 작성 부분을 거의 완료하였습니다. 나중에 실시간 처리를 할 때 다시 건들이게 될 것 입니다. 이 API 가 제대로 작동하는지 확인하기 위하여 다음처럼 테스팅 요청을 넣어보세요
POST http://localhost:4000/api/posts
{
"content": "테스팅테스팅"
}
# 반환값
{
"__v": 0,
"count": 1,
"username": "veloperet",
"content": "테스팅테스팅",
"_id": "595f8972e3d79767f1e35430",
"comments": [],
"likes": [],
"likesCount": 0,
"createdAt": "2017-07-07T13:15:30.095Z"
}
이제 곧 추가 로딩 부분을 구현 해 볼 텐데요, 이를 대비하여 테스트 요청을 최소 25번 정도 반복을 하여 여러개의 포스트를 미리 생성해두세요.