Projects/청하-청년을 위한 커뮤니티 서비스

[청하] 11. 게시글 삭제 기능 구현 (feat. NCP Object Storage 이미지 삭제)

Lpromotion 2024. 10. 9. 01:43

1. 프로젝트 구조

src/main/java/com/example/withpeace/
│
├── domain/                 # 도메인 모델 (엔티티)
│   ├── Image.java          # 이미지 엔티티
│   └── Post.java           # 게시글 엔티티
│
├── repository/             # 데이터 접근 계층
│   ├── ImageRepository.java    # 이미지 레포지토리
│   └── PostRepository.java     # 게시글 레포지토리
│
├── controller/             # 컨트롤러 계층
│   └── PostController.java # 게시글 관련 API 엔드포인트
│
└── service/                # 비즈니스 로직 계층
    └── PostService.java    # 게시글 관련 비즈니스 로직

 

2. 레포지토리 구현

ImageRepository

@Repository
public interface ImageRepository extends JpaRepository<Image, Long> {
    // ... (기존 메서드 생략)

    @Modifying
    @Query("DELETE FROM Image i WHERE i.post = :post")
    void deleteImagesByPost(Post post);
}
  • `@Modifying`: 해당 쿼리가 데이터를 수정한다는 것을 나타낸다.

`deleteImagesByPost` 메서드는 특정 게시글과 관련된 모든 이미지를 삭제한다.

 

3. 컨트롤러 구현

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/v1/posts")
public class PostController {
    // ... (기존 메서드 생략)

    // 게시글 삭제
    @DeleteMapping("/{postId}")
    public ResponseDto<?> deletePost(@UserId Long userId, @PathVariable Long postId) {
        return ResponseDto.ok(postService.deletePost(userId, postId));
    }
}

사용자 ID와 URL 경로에서 추출한 게시글 ID를 서비스로 전달한다.

 

4. 서비스 구현

@Service
@RequiredArgsConstructor
public class PostService {

    private final AmazonS3 amazonS3; // NCP Object Storage 클라이언트
    @Value("${cloud.aws.s3.bucket}")
    private String bucket;
    // ... (기존 코드 생략)

    @Transactional
    public Boolean deletePost(Long userId, Long postId) {
        // 사용자 존재 여부 확인
        userRepository.findById(userId).orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_USER));
        // 게시글 존재 여부 확인
        Post post =
                postRepository.findById(postId).orElseThrow(() -> new CommonException(ErrorCode.NOT_FOUND_POST));

        try {
            // DB에서 해당 게시글과 관련된 이미지 삭제
            imageRepository.deleteImagesByPost(post);

            // NCP Object Storage에서 실제 이미지 삭제
            DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucket);
            deleteObjectsRequest.withKeys("postImage/" + postId);
            amazonS3.deleteObjects(deleteObjectsRequest);

            // DB에서 게시글 삭제
            postRepository.delete(post);

            return true;
        } catch (Exception e) {
		        // 삭제 과정에서 오류 발생 시 예외 처린
            throw new CommonException(ErrorCode.POST_ERROR);
        }
    }

}
  1. 사용자의 존재 여부를 확인하고, 존재하지 않으면 예외를 발생시킨다.
  2. 삭제할 게시글의 존재 여부를 확인하고, 존재하지 않으면 예외를 발생시킨다.
  3. 해당 게시글과 연관된 모든 이미지 정보를 DB에서 삭제한다.
  4. NCP Object Storage에서 실제 이미지를 삭제한다.
    • `DeleteObjectsRequest` 를 사용해 `"postImage/" + postId`로 시작하는 모든 객체를 삭제 대상으로 추가한다.
    • `amazonS3.deleteObjects(deleteObjectsRequest)`로 NCP Object Storage 에서 삭제 대상인 이미지를 삭제한다.
  5. 해당 게시글을 DB에서 삭제한다.
  • `AmazonS3`는 NCP Object Storage를 사용하기 위한 클라이언트이다. `AmazonS3` 인터페이스를 사용하지만, 실제로는 NCP Object Storage의 S3 호환 API를 통해 접근한다.
  • `@Value` 어노테이션을 통해 yml 파일에 정의한 값을 가져온다.
  • `@Transactional` 어노테이션을 사용하기 때문에, 어느 한 단계에서라도 실패하면 전체 작업이 롤백된다.

 

6. API 응답 예시

요청 URL

[DELETE] http://cheongha.site/api/v1/posts/20

 

Response Body

{
  "data": true,
  "error": null
}
반응형