Server/Spring Boot

Chapter 6. 블로그 기획하고 API 만들기

은 딩 2023. 11. 14. 12:27

 

 

1. REST API

  • Representational State Transfer
  • 웹의 장점을 최대한 활용하는 API
  • 자원을 이름으로 구분해 자원의 상태를 주고받는 API 방식
  • URL의 설계 방식

REST API의 장점

  • URL만 보고도 무슨 행동을 하는 API인지 명확하게 알 수 있음
  • 상태가 없다는 특징이 있어서 클라이언트와 서버의 역할이 명확하게 분리
  • HTTP 표준을 사용하는 모든 플랫폼에서 사용할 수 있음

REST API의 단점

  • GET, POST와 같은 방식의 개수에 제한이 있고, 설계를 위해 공식적으로 제공되는 표준 규약이 없음

REST API 사용방법

1. URL에는 동사X, 자원 표시

  • 자원 = 가져오는 데이터
  • ex) 학생 중 id가 1인 학생 정보를 가져오는 URL
    • /students/1
  • /articles/1(O) , /articles/show/1(X)

2. 동사는 HTTP 메서드로


2. 블로그 개발을 위한 엔티티 구성

 

// Article.java

package com.example.springstarter.domain;

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 기본 생성자
public class Article {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="id", updatable = false)
    private Long id;

    @Column(name = "title", nullable = false)
    private String title;

    @Column(name = "content", nullable = false)
    private String content;

    @Builder // 빌더 패턴으로 객체 생성(어느 필드에 어떤 값이 들어가는지 명시적으로 파악)
    public Article(String title, String content){
        this.title = title;
        this.content = content;
    }
}

 

// BlogRepository

package com.example.springstarter.repository;

import com.example.springstarter.domain.Article;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BlogRepository extends JpaRepository<Article, Long> {
}

 


3. 블로그 글 작성을 위한 API 구현

구현 과정

서비스 클래스에서 메서드 구현 => 컨트롤러에서 사용할 메서드 구현 => API 테스트

 

DTO(data transfer object)는 계층끼리 데이터를 교환하기 이해 사용하는 객체(별도의 비즈니스 로직X)

DAO는 DB와 연결되고 데이터를 조회하고 수정하는데 사용하는 객체(데이터 수정과 관련된 로직 포함)

 

// dto/AddArticleRequest.java

package com.example.springstarter.dto;

import com.example.springstarter.domain.Article;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor // 기본 생성자 추가
@AllArgsConstructor // 모든 필드 값을 파라미터로 받는 생성자 추가
@Getter
public class AddArticleRequest {
    private String title;
    private String content;

    // 빌더 패턴으로 DTO 엔티티 만들어주는 메서드
    public Article toEntity() { // 생성자를 사용해 객체 생성
        return Article.builder().
                title(title)
                .content(content)
                .build();
    }
}

 

// BlogService.java

package com.example.springstarter.service;

import com.example.springstarter.domain.Article;
import com.example.springstarter.dto.AddArticleRequest;
import com.example.springstarter.repository.BlogRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor // final이 붙거나 @NotNull이 붙은 필드의 생성자 추가
@Service // 빈으로 등록
public class BlogService {
    private final BlogRepository blogRepository;

    // 블로그 글 추가 메서드
    public Article save(AddArticleRequest request){
        return blogRepository.save(request.toEntity());
    }
}

 

 

// BlogController.java

package com.example.springstarter.controller;

import com.example.springstarter.domain.Article;
import com.example.springstarter.dto.AddArticleRequest;
import com.example.springstarter.service.BlogService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RestController // HTTP Response Body에 객체 데이터를 JSON 형식으로 반환하는 컨트롤러
public class BlogApiController {
    private final BlogService blogService;

    // HTTP 메서드가 POST일 때 절달받은 URL과 동일하면 메서드로 매핑
    @PostMapping("/api/articles")
    // 요청 본문 값 매핑
    public ResponseEntity<Article> addArticle(@RequestBody AddArticleRequest request){
        Article savedArticle = blogService.save(request);

        // 요청한 자원이 성공적으로 생성되었으며 저장된 블로그 글 정보를 응답 객체에 담아 전송
        return ResponseEntity.status(HttpStatus.CREATED)
                .body(savedArticle);
    }
}

 

게시글 목록 조회, 게시글 조회, 게시글 삭제, 수정 API를 구현했는데 코드가 너무 길어서 깃허브에 올려야겠다.

https://github.com/Eundding/springboot3-practice

 

GitHub - Eundding/springboot3-practice: 스프링 부트 3 백엔드 개발자 되기(자바 편) 실습 코드

스프링 부트 3 백엔드 개발자 되기(자바 편) 실습 코드. Contribute to Eundding/springboot3-practice development by creating an account on GitHub.

github.com

 

 


Reference

<스프링 부트 3 백엔드 개발자 되기: 자바 편> 저자 : 신선영