ChatGPT와의 대화
무한 스크롤이란?
사용자가 스크롤을 아래로 내릴 때마다 자동으로 다음 데이터를 불러오는 방식이에요.
페이스북, 인스타그램, 트위터 피드처럼 한 번에 전체 데이터를 불러오는 대신, 조금씩 끊어서 불러오는 구조예요.
GET /posts/liked?userId=1&offset=0&limit=5
EX.
GET /posts/liked?userId=1&offset=5&limit=5
async getPostsLiked(userId, sort, offset = 0, limit = 5) {
// 1. 유저 존재 확인
const user = await this.usersRepository.findOne({ where: { id: userId } });
if (!user) throw new Error('사용자를 찾을 수 없습니다.');
// 2. 정렬 방식 설정
let orderBy: string;
switch (sort) {
case 'oldest': orderBy = 'p.postDatetime ASC'; break;
case 'newest': orderBy = 'p.postDatetime DESC'; break;
case 'most_liked':
case 'least_liked':
orderBy = 'p.postDatetime DESC'; // 좋아요 기준 정렬은 나중에 JS에서 처리
break;
default: orderBy = 'p.postDatetime DESC';
}
// 3. 사용자가 좋아요한 post의 ID만 먼저 가져오기
const postIdRows = await this.dataSource.query(`
SELECT p.id AS postId
FROM post p
INNER JOIN likes l ON l.post_id = p.id
WHERE l.user_id = ?
ORDER BY ${orderBy}
LIMIT ? OFFSET ?
`, [userId, limit, offset]);
const postIds = postIdRows.map((row) => row.postId);
// 4. 각 post의 상세 정보 + 좋아요 수 조회
const postInfos = await this.getPostInfos(postIds);
// 5. 좋아요 수 기준 정렬은 JS에서 처리
if (sort === 'most_liked') {
postInfos.sort((a, b) => b.likeCount - a.likeCount);
} else if (sort === 'least_liked') {
postInfos.sort((a, b) => a.likeCount - b.likeCount);
}
// 6. 클라이언트에 응답할 데이터
return {
'like-list': postInfos,
nextOffset: offset + postInfos.length, // 다음 요청할 offset
hasMore: postInfos.length === limit, // 더 불러올 게 있는지 여부
};
}
@Get('liked/:userId')
async getLikedPosts(
@Request() req: { user: {sub: number} },
@Query('sort') sort?: 'oldest' | 'newest' | 'most_liked' | 'least_liked',
@Query('offset') offset?: string,
@Query('limit') limit?: string
) {
return this.postsService.getPostsLiked(
userId,
sort,
Number(offset ?? 0), // 기본값 0
Number(limit ?? 5) // 기본값 5
);
}
✅ Number(offset ?? 0)
쿼리 파라미터에서 받은 offset은 보통 문자열(string | undefined)이므로 숫자로 변환해야 합니다.
? 0: 값이 null이나 undefined이면 기본값 0을 사용하겠다는 뜻입니다.
예: offset=10 → '10' → Number('10') → 10
예: offset 없음 → undefined ?? 0 → 0
✅ Number(limit ?? 5)
limit도 마찬가지로 없으면 기본값 5 사용합니다.
무한 스크롤에서 한 번에 불러올 항목 수
GET /posts/liked/1?sort=newest&offset=0&limit=5
{
"like-list": [...5개 데이터...],
"nextOffset": 5,
"hasMore": true
}
GET /posts/liked/1?sort=newest&offset=5&limit=5
| 항목 | 설명 |
|---|---|
| limit | 한 번에 몇 개씩 불러올지 |
| offset | 몇 번째부터 가져올지(이전까지 본 항목 수) |
| hasMore | 아직 불러올 게 있는지 |
| nextOffset | 다음에 요청할 offset 값 |