Develop

[Spring Boot] 게시판 - 02. Post API 개발 (페이징 처리, IntelliJ HTTP Client) 본문

백엔드/게시판 만들기

[Spring Boot] 게시판 - 02. Post API 개발 (페이징 처리, IntelliJ HTTP Client)

230801 2025. 11. 20. 05:31

안녕하세요 .ᐟ

오늘은 게시판 프로젝트의 핵심인 Post API 를 구현했습니다.

 

주요 학습 내용

- 연관관계 매핑 (@ManyToOne)

- 페이징 처리 (Pageable, Page)

- DataInitializer를 통한 초기 데이터 자동 생성

- IntelliJ HTTP Client 활용

 

 


 

요구사항

Post (게시글)

  • 제목, 내용, 조회수
  • 작성자와 연관관계
  • 카테고리와 연관관계
  • CRUD
  • 페이징처리

Category (카테고리)

  • Enum (일단 NOTICE, FREE, QNA, TECH 정도만 만들었습니다.)
    • DB에 잘못된 값이 들어가는 것을 컴파일 단계에서 방지할 수 있습니다.
  • 카테고리는 항상있어야되는데 매번 Insert 해주기가 번거로워서 알아보다가 DataInitializer 를 알게되어 바로 적용했습니다.

 


 

 

PostRepository

  • Spring Data JPA의 메서드 쿼리를 활용했습니다:
    • 메서드 쿼리(Query Mehthods)
      • 메서드 이름만으로 쿼리를 자동 생성해주는 기능입니다.
      • 개발자가 SQL 이나 JPQL 을 작성하지않아도, 메서드 이름 규칙에 따라 JPA 가 자동으로 쿼리를 만들어줍니다 b
    • 기본 구조
      • find + 주체 + By + 조건필드 + 조건 키워드 + 정렬
    • 주요 키워드
      • findBy - 조회
      • countBy - 개수
      • existsBy - 존재여부
      • deleteBy - 삭제
    • 조건 키워드
      • Containing - LIKE 검색
      • And - 여러 조건
      • Or 
      • GreaterThan - 초과
      • LessThanEqual - 이하
      • Between
      • OrderBy - 정렬
    • 연관관계 탐색
      • "_" 사용
findByCategory_Id: 카테고리별 조회 (`_`로 연관관계 탐색)
findByAuthor_Id: 작성자별 조회
findByTitleContaining: 제목 검색 (LIKE 쿼리)
  • 모든 조회 메서드는 Page<Post>를 반환하여 페이징을 지원합니다.
    • pageable 을 파라미터로 받으면 자동으로 페이징 쿼리가 생성됩니다.

 

 

PostDetailResponse

  • from 정적 팩토리 메서드 사용 (Entity -> DTO 변환)
  • 변환로직을 DTO 에 캡슐화해서 Controller 에서 사용했습니다.

 

 

PostService

  • 페이징 처리를 위해 Page<Post>로 반환하고, Pageable 을 파라미터로 받아서 페이징의 정보를 처리했습니다.
  • 작성자 검증은 userId로 Post 객체를 조회하고, 꺼내온 id 와 일치하는지 확인했습니다.
  • 조회수 증가 로직에서 변경감지를 활용했습니다.
    • 동작원리
      • @Transactional 시작 → Entity 영속화
      • post.increaseViewCount() → Entity 상태 변경
      • 트랜잭션 커밋 → JPA가 변경된 필드만 자동 UPDATE

 

PostController

  • Entity -> DTO 변환
    • 정적 팩토리 메서드 from() 을 사용해 변환합니다.
  • 페이징 처리
    • map() 메서드로 Page 내부의 Entity 들을 DTO 로 변환합니다.

 

페이징 처리 - 요청 예시

GET /posts?page=0&size=10&sort=createdAt,desc

 

 

페이징 처리 - Controller 구현

@GetMapping
public Page<PostListResponse> findAll(
    @PageableDefault(size = 20, sort = "createdAt", direction = Sort.Direction.DESC) 
    Pageable pageable
) {
    // ...
}

 

 

페이징 처리 - 응답 구조

{
  "content": [
    {"id": 1, "title": "첫 게시글", ...},
    {"id": 2, "title": "두번째", ...}
  ],
  "totalElements": 100,
  "totalPages": 5,
  "size": 20,
  "number": 0,
  "first": true,
  "last": false
}

 

 

 

DataInitializer

  • 개념
    • DataInitializer는 Component 로 등록하면 Application 시작 시 자동으로 초기 데이터를 생성해줍니다.
  • 방법
    • CommandLineRunner 를 implements하고, run()을 오버라이드 해줍니다.
    • 생성할 enum 값 들을 셋팅해줍니다.
@Component
@RequiredArgsConstructor
public class DataInitializer implements CommandLineRunner {

    private final CategoryService categoryService;

    @Override
    public void run(String... args) {
        if (categoryService.findAll().isEmpty()) {
            categoryService.create(CategoryType.NOTICE, "공지사항");
            categoryService.create(CategoryType.FREE, "자유게시판");
            categoryService.create(CategoryType.QNA, "질문");
            categoryService.create(CategoryType.TECH, "기술");
        }
    }
}
  • 장점
    • 매번 SQL로 데이터를 삽입하지않아도 됩니다...굿 
    • 팀원들한테 .sql 파일 안넘겨줘도 됩니다.
    • 개발환경이 통일되어 테스트 환경도 빠르게 구축됩니다.

 

 

API TEST

  • 도구
    • 평소에 API TEST 는 Swagger 나 Postman 으로 했었는데, 이번에는 IntelliJHTTP Client 로 진행해봤습니다.
  • 공식 문서
  • 방법
    • 프로젝트에 .http 파일을 생성한다.
      • 아니면, Controller 에서 Http Method 옆에 있는 지구본 모양을 클릭해도 생성됩니다.
    • + 를 눌러 테스트를 작성합니다.
      • 원하는 Http Method, 테스트주소를 입력하고 컨텐츠 타입명시, 아래 Json 을 입력한뒤 초록색 버튼을 눌러 실행시킨다.
      • test 를 구분하고싶을땐 "### "을 사용하면 됩니다~
    • 결과는 콘솔창에 200, 500 등으로 표시된다.
POST /posts?userId=1
Content-Type: application/json

{
  "title": "첫 게시글",
  "content": "안녕하세요",
  "categoryId": 1
}

 

  • 장점
    • IDE 내장 test 도구라서 이것저것 실행시키거나 설치하지 않아도 돼서 편하다.. b
    • test 아래에 노란색 글씨(타임스탬프)로 응답이 저장된다.
    • file 이라서 git 에 올릴 수 있다.
      • test 내용을 버전관리할 수 있을듯..? 
    • Swagger 는 코드에 설정이 필요한데.. 그 시간이 줄을 것 같고, 사용안해본 사람에게 전달해도 좋을 것 같다.
    • Postman 설치 시간 + 데이터 입력시간을 줄일 수 있다.
    • 환경변수 기능도 지원해서 정말 편합니다.
### 개발 환경
@host = localhost:8080
@userId = 1

GET http://{{host}}/users/{{userId}}

 

 

느낀점

  • Spring Data JPA 의 페이징 기능을 맛봤는데, 제대로 공부해보고 싶은 마음도 생겼습니다.
    • 페이징 처리를 하면 대용량 데이터를 한번에 조회 -> 나눠서 조회 하기때문에 메모리 문제를 방지할 수 있습니다.
  • 변경감지
    • 어제오늘 @Transactional 안에서 Entity 만 수정하면 자동으로 Update 되는게 코드작성할때 너무 기분좋았습니다. (이렇게 코드가 간결해지면 기분좋은거 저만 그런가요 ㅋㅋ)
  • 새로운 API 테스트도구 발견 ~
    • 이름도 몰랐는데, 컨트롤러에서 지구본모양 잠깐눌러보고 뒤로가기 했던 지난날들 너무 아깝습니다.
    • HTTP Client 라는 이름의 기능 너무 편하고, 앞으로 애용할 것 같습니다.
    • 팀활동 시 API TEST 도구가 익숙하지 않은분들에게 추천드립니다.