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 값으로 설정이 되는거죠.

포스트 작성 로직 미리 확인하기

포스트 작성에 대한 로직은 어떻게 이뤄져있는지, 확인을 해볼까요?

  1. 유저 검증
  2. 유저의 thoughtCount 가져오기, 1 더하기
  3. 요청 데이터 스키마 검증하기
  4. 포스트 write 메소드 호출
  5. 요청자에게 포스트 정보반환
  6. 소켓을 통하여 접속중인 유저에게 실시간 포스트 정보 전송

여기서, 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번 정도 반복을 하여 여러개의 포스트를 미리 생성해두세요.

results matching ""

    No results matching ""