실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기

Ch03. 요구사항 추가(type, 대출현황) - 도서 대출 현황 요구사항 추가

webmaster 2022. 11. 6. 13:10
728x90

도서 대출 현황
API 스펙

  • 과거 대출했던 기록, 현재 대출 중인 기록을 보여준다.
  • 아무런 기록이 없는 유저도 화면에 보여야 한다.

위의 요구사항을 추가하기 위해 Dto, Controller,Service 를 만들어 보자

UserLoanHistoryReponse(Dto)


data class UserLoanHistoryResponse(
    val name: String, //유저 이름
    val books: List<BookHistoryResponse>
)
data class BookHistoryResponse(
    val name: String, //책 이름
    val isReturn: Boolean,
)
  • 하나의 User에 책이름, 반납여부 List를 가지고 있는 Dtodlek.

Controller

Controller를 나누는 기준이 여러 가지이다 

  • 화면에서 사용되는 API끼리 모아둔다
    • 장점 : 화면에서 어떤 API가 사용되는지 한눈에 알기 용이
    • 단점 : 한 API가 여러 화면에서 사용되면 위치가 애매, 서버 코드가 화면에 종속적
  • 동일한 도메인끼리 API를 모아둔다.
    • 장점 : 화면 위치와 무관하게 서버 코드는 변경되지 않아도 된다, 비슷한 API끼리 모이게 되며 코드의 위치를 예측할 수 있다.
    • 단점 : 이 API가 어디서 사용되는지 서버 코드만 보고 알기는 힘들다.
  • 1 API 1 Controller를 사용한다.
    • 장점 : 화면 위치와 무관하게 서버 코드는 변경되지 않아도 된다.
    • 단점 : 이 API가 어디서 사용되는지 서버 코드만 보고 알기는 힘들다.

결과적으로는 다른 개발자가 어떤 API가 어떤 Controller에 있는지 빨리 찾을 수 있도록 도와주는 것이 가장 큰 목표이며, 이를 위해 여러 가지 방법을 지원한다.

  1. IntelliJ 전체 검색(mac = cmd + shift + f, window = ctrl + shift + f)
  2. API full URL을 모아두는 KotlinFile 사용
  3. IntelliJ 유료 버전에서 EndPoints 기능 사용

도서 대출 현황 같은 경우에는 동일한 API 끼리 모아두는 방식으로 Controller 작성

@GetMapping("/user/loan")
fun getUserLoanHistories(): List<UserLoanHistoryResponse>{
    return userService.getUserLoanHistories()
}

Service

@Transactional(readOnly = true)
fun getUserLoanHistories(): List<UserLoanHistoryResponse> {
    return userRepository.findAll().map { user ->
        UserLoanHistoryResponse(
            name = user.name,
            books = user.userLoanHistories.map { history ->
                BookHistoryResponse(
                    name = history.bookName,
                    isReturn = history.status == UserLoanStatus.RETURNED
                )
            }
        )
    }
}
  • findAll() 로 모두 User를 모두 조회 한 뒤, 연관되어 있는 History 테이블을 map함수로 변경한다
728x90