api 요청 후, 그에 대한 응답으로 받는 데이터는 크게 세 가지다.
BookController
// 책 단건 조회 → 단일 데이터
@GetMapping(value = /book/{bookId})
public Book getBookById(@PathVariable long bookId) {
return bookService.getBookById(BookId);
}
// 책 목록 조회 → 리스트 데이터
@GetMapping(value = /books/{userId})
public List<Book> getBookList(@PathVariable long userId) {
return bookService.getBooksByUser(userId);
}
BookService
// 책 단건 조회 → 단일 데이터
public Book getBookById(long bookId) {
return bookJpaRepo.findById(bookId).get();
}
// 사용자별 책 목록 조회 → 리스트 데이터
public List<Book> getBookByUser(long userId) {
User user = userJpaRepo.findById(userId).get();
List<Book> bookList = bookJpaRepo.findBooksByUser(user)
return bookList;
}
단건조회 → Book 반환
다중조회 → List< Book> 반환
DB 에 존재하지 않는 책을 조회하려고 할 경우
서버상의 에러가 발생
즉, 가공하지 않고 Entity 를 그대로 반환하게 되면
Entity 가 외부에 그대로 노출되어서, 상황에 따른 에러들을 적절하게 처리할 수 없게 된다.
따라서, 해당 아이디를 가진 책은 존재하지 않는다는 응답을 돌려주기 위해
서버단에서 직접 코드로 문제상황에 따른 에러를 내려주는 과정이 필요하다.
공통 속성
@Getter
class CommonResponse {
boolean success; // ① 응답(response)에 포함될 속성 中 2. 성공 여부
int code; // ① 응답(response)에 포함될 속성 中 3. status code
String message; // ① 응답(response)에 포함될 속성 中 4. 에러에 해당하는 경우 메세지 (에러 발생 요인)
}
SingleResponse<T>
공통속성 + 엔티티 T 의 단일 데이터
@Getter
public class SingleResponse<T> extends CommondResponse {
T data; // ① 응답(response)에 포함될 속성 中 1. 데이터 (엔티티 or 엔티티 리스트)
}
ListResponse<T>
공통속성 + 엔티티 T의 리스트 데이터
@Getter
public class ListResponse <T> extends CommondResponse {
List<T> dataList; // ① 응답(response)에 포함될 속성 中 1. 데이터 (엔티티 or 엔티티 리스트)
}
정리하자면,
CommonResponse 클래스에 공통 속성(success, code, message) 을 부여하고
++ 각각 CommonResponse 를 상속해서 데이터만 추가하면 된다.
반환받은 데이터를 감싸서, Controller단에 넘겨줄 Service 클래스를 생성
@Service
public class ResponseService {
// getSingleResponse : T를 받아 SingleResponse<T> 로 반환
public<T> SingleResponse<T> getSingleResponse(T data) {
SingleResponse singleResponse = new SingleResponse();
singleResponse.data = data;
setSuccessResponse(singleResponse);
return singleResponse;
}
// getListResponse : List<T> 를 받아 ListResponse<T> 로 반환
public<T> ListResponse<T> getListResponse(List<T> dataList) {
ListResponse listResponse = new ListResponse();
listResponse.dataList = dataList;
setSuccessResponse(listResponse);
return listResponse;
}
void setSuccessResponse(CommondResponse response) {
response.code = 0;
response.success = true;
response.message ="success";
}
}
@RestController
RequiredArgsConstructor
public class BookController {
private final BookService bookService;
private final ResponseService responseService;
// 책 단건 조회 → 단일 데이터
@GetMapping(value = /book/{bookId})
public SingleResponse<Book> getBookById(@PathVariable long bookId) {
return responseService.getSingleRespone(bookService.getBookById(BookId));
}
// 책 목록 조회 → 리스트 데이터
@GetMapping(value = /books/{userId})
public ListResponse<Book> getBookList(@PathVariable long userId) {
return responseService.getListResponse(bookService.getBooksByUser(userId));
}
}
수정 전 : public Book getBookById(@PathVariable long bookId)
수정 후 : public SingleResponse< Book> getBookById(@PathVariable long bookId)
→ Book 엔티티를 한 번 더 감쌌다.
수정 전 : return bookService.getBookById(BookId);
수정 후 : return responseService.getSingleRespone(bookService.getBookById(BookId));
→ bookService.getBookById(BookId) 를 한 번 더 감쌌다.
수정 전 : public List< Book> getBookList(@PathVariable long userId)
수정 후 : public ListResponse< Book> getBookList(@PathVariable long userId)
수정 전 : return bookService.getBooksByUser(userId);
수정 후 : return responseService.getListResponse(bookService.getBooksByUser(userId));
→ bookService.getBooksByUser(userId) 를 한 번 더 감쌌다.
단건 조회
다중(List) 조회