NestJS, TypeORM 이해하기
Table of Content
1. 페이징 기능 추가
article.service.ts
•
페이징 처리를 위해서는 쿼리스트링(Param)으로 페이지와 게시글 수를 받아와야 한다.
•
getPaginatedArticles(page: number, limit: number) 메서드 명으로 위 두개의 파라미터를 받아온다.
◦
page : 현재 페이지 번호(1,2,3,…)
◦
limit : 한 개의 페이지당 보여줄 게시글의 수
◦
skip : (page - 1) * limit 를 통해 이전 페이지에서 가져왔던 게시글을 건너뛰기 위한 변수
▪
ex) 2페이지로 접근하면, (2-1) * 10 = 9개 를 건너 뜀
•
TypeORM의 find() 메서드의 페이징 인터페이스 활용
◦
find() 메서드는 skip과 take를 함께 사용하면 페이징이 구현됨
...
import { UserRole } from 'src/user/user-role.enum';
@Injectable()
export class ArticleService {
private readonly logger = new Logger(ArticleService.name); // Logger 인스턴스 생성
constructor(
@InjectRepository(Article)
private articleRepository: Repository<Article>
){}
...
// 전체 게시글 조회
...
// 페이징 추가 게시글 조회 기능
async getPaginatedArticles(page: number, limit: number): Promise<Article[]> {
this.logger.verbose(`Retrieving paginated articles: page ${page}, limit ${limit}`);
const skip: number = (page - 1) * limit;
const articles = await this.articleRepository.find({
skip,
take: limit,
order: { createdAt: 'DESC' } // 내림차순
});
this.logger.verbose(`Paginated articles retrieved successfully`);
return articles;
}
// 나의 게시글 조회
...
}
TypeScript
복사
article.controller.ts
•
getPaginatedArticles( @Query('page') page: number = 1, @Query('limit') limit: number = 10 ) 라는 메서드에 page, limit 두개의 파라미터를 쿼리스트링으로 받아온다.
◦
특별한 입력이 없는 경우에도 기본값으로 1페이지, 10개 게시글을 볼 수 있도록 기본값 설정
•
Service 계층의 getPaginatedArticles() 메서드에 인수로 page, limit을 전달하며 호출
•
게시글 배열 결과를 DTO로 변환하고, 메시지, 상태코드 등과 함께 ApiResponseDto에 맞춰 클라이언트로 응답하게 된다.
...
import { ArticleResponseDto } from './dto/article-response.dto';
@Controller('api/articles')
@UseGuards(AuthGuard('jwt'), RolesGuard) // JWT 인증과 role 커스텀 가드를 적용
export class ArticleController {
private readonly logger = new Logger(ArticleController.name); // Logger 인스턴스 생성
// 생성자 주입(DI)
constructor(private articleService: ArticleService){}
...
// 전체 게시글 조회 기능
...
// 페이징 처리된 게시글 조회
@Get('/paginated')
async getPaginatedArticles( @Query('page') page: number = 1, @Query('limit') limit: number = 10 ): Promise<ApiResponse<ArticleResponseDto[]>> {
this.logger.verbose(`Retrieving paginated articles: page ${page}, limit ${limit}`);
const articles = await this.articleService.getPaginatedArticles(page, limit);
const articleDtos = articles.map(article => new ArticleResponseDto(article));
this.logger.verbose(`Paginated articles retrieved successfully`);
return new ApiResponse(true, 200, 'Paginated articles retrieved successfully', articleDtos);
}
// 나의 게시글 조회 기능
...
}
TypeScript
복사
•
POSTMAN을 통한 테스트
◦
1페이지를 조회하는 경우
▪
29~20번까지 10개 게시글 조회
◦
2페이지를 조회하는 경우
▪
첫페이지(29~20번) 이후인 19~10번까지 10개 게시글 조회
2. 프론트엔드 무한스크롤 참고 자료
프론트엔드에서 무한 스크롤 요청하기 위한 참고자료
•
위 서버 코드를 통해 백엔드 API는 페이지가 증가하는 것에 대해서 계속해서 다음 페이지의 게시글들을 반환할 준비가 되어있다.
•
프론트엔드는 백엔드 API에 요청 할 때 다음과 같은 예시로 page를 1씩 증가시키는 로직이 필요하다.
•
아래 예시는 jQuery의 Ajax 요청 코드로 구성되어 있다. 필요 시 동일한 로직으로 Fetch Api 또는 HttpClient로 구현코드를 변경해도 된다.
◦
변수는 page = 1, limit = 10으로 초기화 되어 있다.
▪
let: 변수의 값을 변경할 수 있는 경우에 사용
▪
const: 변수의 값을 한 번 설정하면 변경할 수 없는 경우에 사용
◦
브라우저의 scroll 에서 특정 높이에 다다를때마다 loadArticles() 함수를 호출되고 있다.
▪
요청 시 마다 page, limit 변수에 할당된 값을 쿼리스트링 데이터로 전달하고 있다.
•
이 요청은 /api/articles/paginated?page=1&limit=10 과 같다.
▪
요청에 성공하면 게시글을 붙여넣는 추가 로직이 구성되어야 한다.
▪
이후 초기화된 page의 값을 증가시킨다(1→2)
let page = 1;
const limit = 10;
function loadArticles() {
$.ajax({
url: `/api/articles/paginated`,
method: 'GET',
data: {
page: page,
limit: limit
},
success: function(response) {
// DOM에 게시글 추가
const articles = response.data; // 응답 구조에 맞게 조정
articles.forEach(article => {
// 게시글을 목록에 추가
});
page++;
},
error: function(xhr, status, error) {
console.error('게시글을 가져오는 중 오류 발생:', error);
}
});
}
// 초기 게시글 로드
loadArticles();
// 스크롤 시 더 많은 게시글 로드
$(window).on('scroll', () => {
if ($(window).scrollTop() + $(window).height() >= $(document).height()) {
loadArticles();
}
});
TypeScript
복사
•
기본적으로 이런 흐름의 스크립트가 필요하며 선택된 프레임워크에 따라 코드를 튜닝하여 사용할 수 있다.
Related Posts
Search