Backend
home
🖋️

2일차

생성일
2024/07/08 14:57
태그
본 프로젝트는 “스프링부트 3 백엔드 개발자 되기” 서적을 참고하여 진행하였음

블로그의 모든 글 조회하는 API 구현

BlogService.java
package com.example.msblog.service; import com.example.msblog.domain.Article; import com.example.msblog.dto.AddArticleRequest; import com.example.msblog.repository.BlogRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.List; @RequiredArgsConstructor // final이 붙거나 @NotNull이 붙은 필드의 생성자 추가 @Service // 빈으로 등록 public class BlogService { private final BlogRepository blogRepository; // 블로그 글 추가 메서드 public Article save(AddArticleRequest request) { return blogRepository.save(request.toEntity()); } // 모든 글 조회 public List<Article> findAll() { return blogRepository.findAll(); } }
Java
복사

응답을 위한 DTO 생성

ArticleResponse.java
package com.example.msblog.service; import com.example.msblog.domain.Article; import com.example.msblog.dto.AddArticleRequest; import com.example.msblog.repository.BlogRepository; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.util.List; @RequiredArgsConstructor // final이 붙거나 @NotNull이 붙은 필드의 생성자 추가 @Service // 빈으로 등록 public class BlogService { private final BlogRepository blogRepository; // 블로그 글 추가 메서드 public Article save(AddArticleRequest request) { return blogRepository.save(request.toEntity()); } // 모든 글 조회 public List<Article> findAll() { return blogRepository.findAll(); } }
Java
복사

전체 글을 조회한 뒤 반환

BlogApiController.java
package com.example.msblog.controller; import com.example.msblog.domain.Article; import com.example.msblog.dto.AddArticleRequest; import com.example.msblog.dto.ArticleResponse; import com.example.msblog.service.BlogService; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RequiredArgsConstructor @RestController // HTTP RESPONSE BODY에 객체 데이터를 JSON 형태로 반환 public class BlogApiController { private final BlogService blogService; // HTTP 메서드가 POST일 때 전달받은 URL과 동일하면 메서드로 매핑 @PostMapping("/api/articles") // @RequestBody로 요청 본문 값 매핑 public ResponseEntity<Article> addArticle(@RequestBody AddArticleRequest request) { Article savedArticle = blogService.save(request); // 요청한 자원이 성공적으로 생성되었으며 저장된 블로그 글 정보를 응답 객체에 담아 전송 return ResponseEntity.status(HttpStatus.CREATED) .body(savedArticle); } // 전체 글을 조회한 뒤 반환하는 findAllArticles() 메서드 추가 // /api/articles GET 요청이 오면 글 전체를 조회하는 findAll() 메서드 호출한 다음 // 응답용 객체인 ArticleResponse로 파싱해 body에 담아 클라이언트에게 전송 // stream: 여러 데이터가 모여 있는 컬렉션을 간편하게 처리하기 위한 기능 @GetMapping("/api/articles") public ResponseEntity<List<ArticleResponse>> findAllArticles() { List<ArticleResponse> articles = blogService.findAll() .stream() .map(ArticleResponse::new) .toList(); return ResponseEntity.ok().body(articles); } }
Java
복사

테스트를 위한 sql 파일 생성

쿼리 작성
INSERT INTO article (title, content) VALUES ('제목 1', '내용 1') INSERT INTO article (title, content) VALUES ('제목 2', '내용 2') INSERT INTO article (title, content) VALUES ('제목 3', '내용 3')
SQL
복사
Postman 테스트 결과

블로그 글 전체 조회 위한 테스트 코드 작성

given-when-then
Given
When
Then
블로그 글 저장
목록 조회 API 호출
응답 코드가 200 OK 이고 반환받은 값 중에 0번째 요소의 content와 title이 저장된 값과 같은지 확인
BlogApiControllerTest
@DisplayName("findAllAritcles: 블로그 글 목록 조회에 성공한다.") @Test public void findAllArticles() throws Exception { // given final String url = "/api/articles"; final String title = "title"; final String content = "content"; blogRepository.save(Article.builder() .title(title) .content(content) .build()); // when final ResultActions resultActions = mockMvc.perform(get(url) .accept(MediaType.APPLICATION_JSON)); // then resultActions .andExpect(status().isOk()) .andExpect(jsonPath("$[0].content").value(content)) .andExpect(jsonPath("$[0].title").value(title)); }
Java
복사

블로그 글 하나를 조회하기 위한 서비스, 컨트롤러 구현

BlogService.java
// 블로그 글 하나를 조회, 조회 후 글이 없으면 예외 처리 public Article findById(long id) { return blogRepository.findById(id) .orElseThrow(() -> new IllegalArgumentException("not found: " + id)); }
Java
복사
BlogApiController.java
// @PathVariable => URL에서 값을 가져오는 애너테이션 // /api/articles/3 GET 요청 받을 시 id에 3이 들어옴 // findById() 메서드로 넘어가 3번 블로그 글을 찾음 @GetMapping("/api/articles/{id}") // URL 경로에서 값 추출 public ResponseEntity<ArticleResponse> findArticle(@PathVariable long id) { Article article = blogService.findById(id); return ResponseEntity.ok().body(new ArticleResponse(article)); }
Java
복사

블로그 글 하나 조회하기 위한 테스트 코드 작성

given-when-then
Given
When
Then
블로그 글 저장
저장한 블로그 글의 id값으로 API 호출
응답 코드가 200 OK 이고 반환받은 content와 title이 저장된 값과 같은지 확인
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)); }
Java
복사