spring/게시판 api

Spring boot 게시판 API 서버 제작 (20) - 게시글 - 조회

얼킴 2023. 3. 4. 16:48

이번에는 게시글 API 조회 기능을 구현해보겠습니다.

 

PostRepository

게시글을 조회할때는 작성자의 정보도 포함해서 조회할 것이기 때문에 Post를 조회할 때 Member를 함께 조회하는 쿼리를 작성해줍니다.

public interface PostRepository extends JpaRepository<Post, Long> {

    @Query("select p from Post p join fetch p.member where p.id = :id")
    Optional<Post> findByIdWithMember(@Param("id") Long id);
}

쿼리의 실행 결과는 Post Entity와 연관된 Member Entity를 함께 가져오며, 이를 통해 게시물과 회원 정보를 모두 조회할 수 있습니다.

 

DTO

다음으로 데이터를 전송 객체인 Dto를 생성하겠습니다.

ImageDto

@Data
@AllArgsConstructor
public class ImageDto {
    private Long id;
    private String originName;
    private String uniqueName;
    public static ImageDto toDto(Image image){
        return new ImageDto(image.getId(), image.getOriginName(), image.getUniqueName());
    }
}

PostDto

@Data
@AllArgsConstructor
public class PostDto {
    private Long id;
    private String title;
    private String content;
    private MemberDto memberDto;
    private List<ImageDto> images;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul")
    private LocalDateTime createdAt;
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "Asia/Seoul")
    private LocalDateTime modifiedAt;

    public static PostDto toDto(Post post){
        return new PostDto(
                post.getId(),
                post.getTitle(),
                post.getContent(),
                MemberDto.toDto(post.getMember()),
                post.getImages().stream().map(i->ImageDto.toDto(i)).collect(Collectors.toList()),
                post.getCreatedAt(),
                post.getModifiedAt()
        );
    }
}

Post타입의 입력값을 받아 PostDto로 만들어주는 메서드까지 추가했습니다.

PostService

이제 PostService에 read 메서드를 추가하겠습니다.

public PostDto read(Long id){
    return PostDto.toDto(postRepository.findById(id).orElseThrow(PostNotFoundException::new));
}

id를 파라미터로 받아 해당 Post를 PostDto로 변환하여 반환합니다.

 

PostController

@ApiOperation(value = "게시글 조회", notes = "게시글을 조회한다.")
@GetMapping("/api/posts/{id}")
@ResponseStatus(HttpStatus.OK)
public Response read(@ApiParam(value = "게시글 id", required = true) @PathVariable Long id) {
    return Response.success(postService.read(id));
}

성공하면 PostDto를 반환해줍니다.

 

결과

 

테스트

테스트는 이전과 동일하여 한번에 보여주도록 하겠습니다.

더보기

PostRepositoryTest

public void findByIdWitdhMemberTest(){
    //given
    Post post = postRepository.save(createPost(member, category));

    //when
    Post foudPost = postRepository.findByIdWithMember(post.getId()).orElseThrow(PostNotFoundException::new);


    //then
    Member foundMember = foudPost.getMember();
    assertThat(foundMember.getEmail()).isEqualTo(member.getEmail());
}

 

PostServiceTest

@Test
public void readTest(){
    //given
    Post post = createPostWithImages(List.of(createImage(), createImage()));
    given(postRepository.findById(anyLong())).willReturn(Optional.of(post));

    //when
    PostDto postDto = postService.read(1L);

    //then
    assertThat(postDto.getImages().size()).isEqualTo(post.getImages().size());
}
@Test
void readExceptionByPostNotFoundTest() {
    // given
    given(postRepository.findById(anyLong())).willReturn(Optional.ofNullable(null));

    // when, then
    assertThatThrownBy(() -> postService.read(1L)).isInstanceOf(PostNotFoundException.class);
}

 


궁금한신점이나 잘못된 부분이 있으면 자유롭게 댓글 달아주세요.

github : https://github.com/jaeyeon423/spring_board_api