토이프로젝트: 공감 기능 만들기(1)
글에 공감할 수 있는 기능인 좋아요 버튼을 만드는 중이다.
서버 DB table 만들기
- 필요한 정보: 사용자가 공감한 글
- id, user id, post id
- create, update date는 아직 왜 있는지 모르겠으나, 읽은 목록을 구현할 때 유용하게 사용하리라 보아 추가하였다.
- uuid를 생성할 때 3rd party로 설치하고 uuid_generate_v4로 default값을 주면 된다고 한다.
why DB?
- 공감을 하면 하트가 눌러진 표시가 된다! DB, 캐싱, local state일지 모를 땐 요구사항을 명세해보면 된다.
- 요구사항
- 공감을 누르면 button에 계속 눌러진 표시가 나야한다: local state
- 브라우저 혹은 세션을 종료해도 다시 이 글을 눌렀을 때 계속 눌러진 표시가 나야한다: 캐싱
- 다른 기기로 접속해도 계속 눌러진 표시가 나야한다: DB
- 이렇게 순서대로 생각해보면 쉽다.
공감을 누른 velog 예시 화면
REST API 만들기
글에대한 공감 정보 가져오는 GET API
- user가 특정 post를 like 했는지 가져온다.
/:userName/liked/:postId
- table에 있는지 체크만하는 select 쿼리 사용
공감, 공감 취소하는 POST API
- user가 특정 post를 like하거나 unlike한 api
/:userName/like/:postId
/:userName/unlike/:postId
- table에 insert하거나 delete하는 쿼리를 사용
- INSERT INTO public."POST_LIKES" ~ VALUES ~
- DELETE FROM public."POST_LIKES" WHERE ~
- 사실 db 업데이트 전에 사전 조건을 체크해야 하는데, 이미 데이터가 있는지 post는 존재하는지를 확인해야한다.
- post가 있는지 select 문으로 확인하고 없으면 404 에러를 반환
- post가 있으나, 이미 공감/비공감 처리된 데이터면 204나 304로 HTML error state 의미를 참고하여 반환하였다.
const postResult = await dbConn.query(`SELECT id FROM public."BLOG_POSTS" WHERE ~`);
if (postResult.rowCount === 0) {
return response.status(404).json({ err: 'Post Not Found' });
}
const alreadyLiked = await dbConn.query(
`SELECT id FROM public."POST_LIKES" WHERE ~
);
if (!alreadyLiked.rowCount) {
return response.status(204).json({ err: 'Post Not Liked' });
}
- 후속작업으로 post table에 like된 모든 count값도 있어서 sync를 맞춰야 하는데 sql로 수동으로 업데이트 했는데 맞는지 모르겠다.
const countResult = await dbConn.query(
`SELECT COUNT(*) FROM public."POST_LIKES" WHERE ~;`
);
try {
await dbConn.query(
`UPDATE public."BLOG_POSTS" SET ~ WHERE ~;`
);
} catch (e) {
return e;
}
좋아요한 모든 글의 목록을 보여주는 GET API
- readling list 기능을 도드라지게 'readingList' 키워드를 먼저 앞세웠으나 오류인거 같다..
/readingList/:userName/liked/
- 의논사항: reading list 자원은 user에게 속하니 순서를 바꿀것인가?
/:userName/readingList/liked/
문제점
post id(uuid)를 이용하니 post를 api로 받은 후에 요청해야하는 비효율적 형태가 되었다.
useEffect(() => {
axios({
baseURL: API_HOST,
url: `/@${userId}/${urlSlug}`,
})
.then(response => {
const _post = response.data;
setPost(_post);
axios({
baseURL: API_HOST,
url: `/${userId}/liked/${_post.id}`,
}).then(reponse => {
setLiked(reponse.data.length !== 0);
});
console.log(response.data);
})
.catch(error => {
console.error(error);
});
}, [userId, urlSlug]);
- 그래서 해결방법으로 post url로 별도로 요청하는 방법을 생각 중이다.
- api 수정:
/${userId}/liked/${urlSlug}
, - 내부적으로 db에서 urlSlug로 post id를 select하여 다시 like 정보를 select하는 중첩 select 쿼리를 쓸 예정이다.
- api 수정:
TODO
- user like api 수정
- 공감 component 구현 완료
- 읽은 목록 page 구현
Author And Source
이 문제에 관하여(토이프로젝트: 공감 기능 만들기(1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@coolchaem/토이프로젝트-공감-기능-만들기1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)