본문 바로가기

Spring boot/Blog 프로젝트 만들기(JPA)

[Blog] 블로그 프로젝트 만들기 - 6 (글 상세보기 조회 API )

package com.example.demo._domain.blog.service;

import java.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo._domain.blog.controller.ApiUtil;
import com.example.demo._domain.blog.dto.ArticleDTO;
import com.example.demo._domain.blog.entity.Article;
import com.example.demo._domain.blog.repository.PostRepository;
import com.example.demo.common.errors.Exception400;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
@Service // IoC (빈으로 등록)
public class BlogService {

    @Autowired // DI <- 개발자들이 가독성 때문에 작성을 해준다.
    private final PostRepository postRepository;

    @Transactional // 쓰기 지연 처리까지
    public Article save(ArticleDTO dto){
        // 비즈니스 로직이 필요하다면 작성
        return postRepository.save(dto.toEntity());
    }

    // 전체 게시글 조회 기능
    public List<Article> findAll(){
       List<Article> articles =  postRepository.findAll();
       return articles;
    }

    // 상세보기 게시글 조회
    public Article findById(Integer id){
        // Optional<T>는 Java 8에서 도입된 클래스이며, 
		// 값이 존재할 수도 있고 없을 수도 있는 상황을 명확하게 처리하기 위해 사용됩니다.
		// Optional 타입에 대해서 직접 조사하고 숙지 하세요(테스트 코드 작성)
        return postRepository.findById(id).orElseThrow(() -> new Exception400("해당 게시글이 없습니다."));
    }

}

Optional<T> (Optional을 사용하여 null 처리를 안전처리 하기 위함)

  • 값이 존재할 때: Optional 안에 값이 포함되어 있으며, 이 값을 안전하게 꺼내어 사용할 수 있다.
  • 값이 없을 때: Optional이 비어 있으며, 이를 통해 null을 직접 처리하는 대신, 다양한 메서드를 사용하여 비어있는 상황을 처리할 수 있다.

 

 

 

BlogApiController
package com.example.demo._domain.blog.controller;

import java.util.*;

import org.apache.tomcat.util.http.parser.MediaType;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo._domain.blog.dto.ArticleDTO;
import com.example.demo._domain.blog.entity.Article;
import com.example.demo._domain.blog.service.BlogService;
import com.example.demo.common.ApiUtil;
import com.example.demo.common.errors.Exception400;

import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor // final을 사용했기 때문에 초기화 자동 설정
@RestController // @Controller + @ResponseBody
public class BlogApiController {

    private final BlogService blogService;

    // URL 즉, 주소 설계 http://localhost:8080/api/articles
    @PostMapping("/api/articles")
    public ResponseEntity<Article> addArticle(@RequestBody ArticleDTO dto) {
        // 1. 인증검사
        // 2. 유효성 검사
        Article savedArticle = blogService.save(dto);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedArticle);
    }

    // URL 즉, 주소 설계 http://localhost:8080/api/articles
    @GetMapping("/api/articles")
    public ApiUtil<?> getAllArticles() {
        List<Article> articles = blogService.findAll();
        if (articles.isEmpty()) {
            if (articles.isEmpty()) {
                // return new ApiUtil<>(new Exception400("게시글이 없습니다."));
                throw new Exception400("게시글이 없습니다.") ;
            }
        }

        return new ApiUtil<>(articles);
    }

    // URL 즉, 주소 설계 http://localhost:8080/api/articles/1
    @GetMapping("/api/articles/{id}")
    public ApiUtil<?> findArticles(@PathVariable(name = "id") Integer id) {

        // 1. 유효성 검사 생략
        Article article = blogService.findById(id);
        return new ApiUtil<>(article);
    }

}
728x90