[toyproject] 웹 애플리케이션 만들기3 - 시험용 api 코드 작성

한지연·2023년 6월 29일
0

지금은 간단하게 시험용 api를 만드는 중이다.

  • controller
@RestController
@RequestMapping("/photo")
@Slf4j
@RequiredArgsConstructor
public class PhotoController {

    private final PhotoService photoService;

    private final String fileDir = "upload-storage";

    @PostMapping("/upload/{userId}")
    public PhotoList uploadFile(@PathVariable("userId") String userId,
                                @RequestBody MultipartFile file) throws IOException {
        log.info("multipartFile={}", file);

        if(file.isEmpty()) throw new IllegalArgumentException();
            String fullPath = fileDir +file.getOriginalFilename();
            log.info("파일 저장 fullPath ={}", fullPath);
            file.transferTo(new File(fullPath));

        return photoService.save(userId, fullPath);
    }

    @GetMapping("/list")
    public List<PhotoList> photoList(){
        return photoService.list();
    }

    @DeleteMapping("/delete/{photoNo}")
    public void deletePhoto(@PathVariable("photoNo") Long photoNo,
                            @RequestParam("userId") String userId) {
        photoService.delete(photoNo, userId);

    }

    @GetMapping("/like/{photoNo}")
    public void likePhoto(@PathVariable("photoNo") Long photoNo){
        photoService.like(photoNo);
    }
  • service
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class PhotoService {

    private final PhotoListRepository photoListRepository;

    private final UserRepository userRepository;


    @Transactional
    public PhotoList save(String userId,String filePath) {

        User user = userRepository.findByUserStrId(userId);


        return photoListRepository.save(new PhotoList(user, filePath));
    }

    public List<PhotoList> list() {
        return photoListRepository.findAll();
    }

    @Transactional
    public void delete(Long photoNo, String userId) {

        PhotoList photo = photoListRepository.findById(photoNo).orElseThrow(IllegalArgumentException::new);

        User user = userRepository.findByUserStrId(userId);

        System.out.println("user.getId(): " + user.getId());
        System.out.println("photo.getUser().getId(): " + photo.getUser().getId());

        if(user.getId() != photo.getUser().getId()) throw new IllegalArgumentException();

        photoListRepository.delete(photo);

    }

    @Transactional
    public void like(Long photoNo) {

        photoListRepository.addCount(photoNo);

    }

like 메소드 같은 경우 원래 더티체킹으로 만들려고 했으나 자꾸 count 변경 감지가 안 돼서 그냥 querydsl repository에 쿼리를 작성했다.

  • Repository
public interface PhotoListRepository extends JpaRepository<PhotoList, Long>, PhotoCustomRepository {
}

---------------------------------------------

public interface PhotoCustomRepository {

    public void addCount(Long photoNo);
}

----------------------------------------------

@RequiredArgsConstructor
public class PhotoCustomRepositoryImpl implements PhotoCustomRepository{

    private final JPAQueryFactory queryFactory;

    @Override
    public void addCount(Long photoNo) {
        queryFactory
                .update(photoList)
                .set(photoList.likes ,photoList.likes.add(1)).where(photoList.id.eq(photoNo))
                .execute();
    }
}
  • domain
@Entity
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class PhotoList {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "photo_id")
    private Long id;

    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_no")
    private User user;

    private String image;

    public void setImage(String image) {
        this.image = image;
    }

    @Column(columnDefinition = "integer default 0")
    private Integer likes;

	// 해당 부분 없애기
    public void addLikesCount(){
        this.likes = likes++;

    }

    @JsonIgnore
    @Column(name="upload_date", columnDefinition = "TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
    @CreationTimestamp
    private LocalDateTime uploadDate;

    @JsonIgnore
    @Column(name ="modify_date")
    @UpdateTimestamp
    private LocalDateTime modifyDate;

    @Column(columnDefinition = "boolean default false")
    private boolean deleted;

    public PhotoList(User user, String image) {
        this.likes = 0;
        this.user = user;
        this.image = image;
    }
}

columnDefinition을 설정했음에도 불구하고 insert 할 때마다 likes가 자꾸 null로 들어가서 쉬운방법으로 생성자에 0을 할당하는 방법을 택했다. 근데 이런 방법은 마음에 안 들어서 더 검색하고 고민해봐야 할 듯 하다.

🧐 고민점

아직 완전한 api를 작성한 것은 아니지만 몇몇 api를 작성할 때 이런 고민이 들었다. jpa 더티체킹을 사용할까 아니면 그냥 querydsl로 작성해서 사용할까? 오늘 like() 메소드 같은 경우도 그렇지만 어제 다른 시험 api들을 작성할 때도 이런 고민이 드는 경우가 더러 있었다. 사용하려는 데이터가 흐름상으로 볼 때 영속성 엔티티일지 준영속엔티티일지 생각해보고 코드를 작성하는 쪽으로 해야겠다는 기준을 세우긴 했는데 다른 조건들도 고려해야 할 수 있다보니 그냥 속 편하게 둘 중에 하나로만 쓰고 싶은 생각이 든다.😭😭😭

profile
배우고 활용하는 것을 즐기는 개발자, 한지연입니다!

0개의 댓글

Powered by GraphCDN, the GraphQL CDN