// service - BlogService.java
@RequiredArgsConstructor // 의존성 주입.
@Service // 빈으로 등록
public class BlogService {
private final BlogRepository blogRepository;
~ 생략 ~
public Article findById(long id){
return blogRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("not found: " + id));
}
}
findById()
JPA에서 제공하는 메서드로, ID를 인자로 받아 엔티티를 조회하여 데이터를 반환한다.
orElseThrow(Object o)
Optional 클래스의 메서드 중 하나이다. 해당 메서드는 Null 값을 반환할 가능성이 있는 경우에 사용되며, 예외를 발생시키며 인자의 객체를 던지는 기능을 제공한다.
- Optional 클래스
Optional 클래스는 자바 8에서 도입된 클래스로, 값이 존재할 수도 있고 없을 수도 있는 값을 감싸는 래퍼 클래스이다. 이 클래스는 NullPointerException을 방지하고 코드의 안정성을 높이는 데 사용된다.
IllegalArgumentException(String message)
자바의 표준 런타임 예외 클래스 중 하나로, 메서드에 잘못된 인수가 전달되었을 때 발생하고 인자로 받은 메시지를 출력한다.
// controller - BlogApiController.java
@RequiredArgsConstructor
@RestController // HTTP Response Body에 객체 데이터를 JSON 형식으로 반환하는 컨트롤러
public class BlogApiController {
private final BlogService blogService;
~ 생략 ~
@GetMapping("/api/articles/{id}")
public ResponseEntity<ArticleResponse> findArticle(
@PathVariable long id) {
Article article = blogService.findById(id);
return ResponseEntity.ok()
.body(new ArticleResponse(article));
}
}
// test - BlogApiControllerTest.java
@SpringBootTest // 테스트용 애플리케이션 컨텍스트
@AutoConfigureMockMvc // MockMvc 생성
class BlogApiControllerTest {
~ 생략 ~
@DisplayName("findArticle: 블로그 글 조회에 성공한다.")
@Test
public void findArticle() throws Exception {
// given
final String url = "/api/articles/{id}";
final String title = "title";
final String content = "content";
Article savedArticle = blogRepository.save(Article.builder()
.title(title)
.content(content)
.build());
// when
final ResultActions resultActions = mockMvc.perform(get(url, savedArticle.getId()));
// then
resultActions
.andExpect(status().isOk())
.andExpect(jsonPath("$.content").value(content))
.andExpect(jsonPath("$.title").value(title));
}
}