블로그 기획하고 API 만들기 (2)

·2023년 12월 2일
0

Spring Boot

목록 보기
9/21
post-thumbnail

이전 포스팅에서 이어집니다!
✨ 블로그 기획하고 API 만들기 (1) ✨


👀 블로그 기획하고 API 만들기 두 번째

1. 블로그 글 목록 조회 API 구현

1-1. 서비스 메소드 코드 작성

BlogService.java

(생략)
   // 데이터베이스에 저장되어 있는 모든 글을 가져오는 메소드
    public List<Article> findAll(){
        return blogRepository.findAll();
    }

1-2. 컨트롤러 메소드 코드 작성

ArticleResponse.java

package me.ansoohyeon.springbootdeveloper.dto;

import lombok.Getter;
import me.ansoohyeon.springbootdeveloper.domain.Article;

@Getter
public class ArticleResponse {

    private final String title;
    private final String content;

    public ArticleResponse(Article article){
        this.title = article.getTitle();
        this.content = article.getContent();
    }
}

BlogApiController.java

(생략)
    @GetMapping("/api/articles")
    public ResponseEntity<List<ArticleResponse>> findAllArticles(){
        List<ArticleResponse> articles = blogService.findAll()
                .stream()
                .map(ArticleResponse::new)
                .toList();

        return ResponseEntity.ok()
                .body(articles);
    }

1-3. 실행 테스트

data.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')

그리고 포스트맨으로 데이터를 조회해 보면 INSERT가 제대로 된 모습이다!

1-4. 테스트 코드 작성

BlogApiControllerTest.java

(생략)
    @DisplayName("findAllArticles : 블로그 글 목록 조회에 성공한다.")
    @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));
    }

테스트 성공!


2. 블로그 글 하나 조회 API 구현

2-1. 서비스 메소드 코드 작성

BlogService.java

(생략)
    // 데이터베이스에 저장되어 있는 글 하나 가져오는 메소드
    public Article findById(long id){
        return blogRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("not found : " + id));
    }

2-2. 컨트롤러 메소드 코드 작성

BlogApiController.java

(생략)
    @GetMapping("/api/articles/{id}")
    // URL 경로에서 값 추출
    public ResponseEntity<ArticleResponse> findArticle(@PathVariable long id){
        Article article = blogService.findById(id);

        return ResponseEntity.ok()
                .body(new ArticleResponse(article));
    }

2-3. 테스트 코드 작성

BlogApiControllerTest.java

(생략)
    @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));
    }

역시나 테스트 성공! 👍


3. 블로그 글 삭제 API 구현

3-1. 서비스 메소드 코드 작성

BlogService.java

(생략)
    // 블로그 글 삭제 메소드
    public void delete(long id){
        blogRepository.deleteById(id);
    }

3-2. 컨트롤러 메소드 코드 작성

BlogApiController.java

(생략)
    @DeleteMapping("/api/articles/{id}")
    public ResponseEntity<Void> deleteArticle(@PathVariable long id){
        blogService.delete(id);

        return ResponseEntity.ok()
                .build();
    }

3-3. 실행 테스트

포스트맨으로 Delete 실행 후 get을 실행하면 정말로 삭제가 된 모습이다! 이 부분은 간단하니 생략하도록 하겠다.

3-4. 테스트 코드 작성

BlogApiControllerTest.java

(생략)
    @DisplayName("deleteArticle : 블로그 글 삭제에 성공한다.")
    @Test
    public void deleteArticle() 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
        mockMvc.perform(delete(url, savedArticle.getId()))
                .andExpect(status().isOk());

        // then
        List<Article> articles = blogRepository.findAll();

        assertThat(articles).isEmpty();
    }

삭제까지 모두 테스트 성공이다. 😉


4. 블로그 글 수정 API 구현

드디어 마지막... 수정이다..!

4-1. 서비스 메소드 코드 작성

Articles.java

(생략)
    public void update(String title, String content){
        this.title = title;
        this.content = content;
    }

UpdateArticleRequest.java

package me.ansoohyeon.springbootdeveloper.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class UpdateArticleRequest {
    private String title;
    private String content;
}

BlogService.java

    // 블로그 글 수정 메소드
    @Transactional // 트랜잭션 메소드
    public Article update(long id, UpdateArticleRequest request) {
        Article article = blogRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("not found : " + id));

        article.update(request.getTitle(), request.getContent());

        return article;
    }

4-2. 컨트롤러 메소드 코드 작성

BlogApiController.java

(생략)
    @PutMapping("/api/articles/{id}")
    public ResponseEntity<Article> updateArticle(@PathVariable long id, @RequestBody UpdateArticleRequest request){
        Article updateArticle = blogService.update(id, request);

        return ResponseEntity.ok()
                .body(updateArticle);
    }

4-3. 실행 테스트

이 부분도 생략하겠다!

4-4. 테스트 코드 작성

BlogApiControllerTest.java

(생략)
    @DisplayName("updateArticle: 블로그 글 수정에 성공한다.")
    @Test
    public void updateArticle() 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());

        final String newTitle = "new title";
        final String newContent = "new content";

        UpdateArticleRequest request = new UpdateArticleRequest(newTitle, newContent);

        // when
        ResultActions result = mockMvc.perform(put(url, savedArticle.getId())
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .content(objectMapper.writeValueAsString(request)));

        // then
        result.andExpect(status().isOk());

        Article article = blogRepository.findById(savedArticle.getId()).get();

        assertThat(article.getTitle()).isEqualTo(newTitle);
        assertThat(article.getContent()).isEqualTo(newContent);
    }

이렇게 모든 기능의 테스트를 성공했다!


🙌 마치며

스프링 부트를 사용해서 CRUD를 작성하는 방법과 테스트 코드를 작성하는 방법을 예제와 함께 살펴보았다. CRUD는 모든 기능의 기반이 되는 기능이고 이번에 작성한 코드 또한 프로젝트 진행 시 가장 기초적인 모델이므로 익숙해지는 것이 중요하겠다. ✨

profile
풀스택 개발자 기록집 📁

0개의 댓글