본문 바로가기

Back-end/Spring boot

[Spring boot] 11일차_HTTP와 REST 컨트롤러

REST API의 의미

  • REST : HTTP URL로 서버의 자원을 명시하고, HTTP 메서드(POST, GET, PATCH/PUT, DELETE)로 해당 자원에 대해 CRUD(생성, 조회, 수정, 삭제)하는 것을 말함
  • API : 클라이언트가 서버의 자원을 요청할 수 있도록 서버에 제공하는 인터페이스

-> REST API란 REST 기반으로 API를 구현한 것. REST API를 잘 구현하면 클라이언트가 기기에 구애받지 않고 서버의 자원을 잘 이용할 수 있음. 또한 클라이언트의 요청에 서버가 체계적으로 대응할 수 있어 서버 프로그램의 재사용성, 확장성이 좋아짐

 

 

REST API구현

REST API로 요청과 응답을 주고 받을 때는 REST 컨트롤러를 사용함. 또한 응답할 때 적절한 상태 코드를 반환하기 위해 

ResponseEntity라는 클래스도 활용됨.

REST 컨트롤러와 ResponseEntity의 역할

 

 

REST 컨트롤러와 일반 컨트롤러의 차이

 

일반 컨트롤러

일반 컨트롤러는 mustache 파일을 반환함.

응답 BODY에서 HTML코드가 있음

 

 

REST API 컨트롤러
REST 컨트롤러

 

일반 컨트롤러는 뷰 페이지를 반환.

REST 컨트롤러는 JSON이나 텍스트 같은 데이터를 반환

 

 

package com.example.firstproject.api;

import com.example.firstproject.dto.ArticleForm;
import com.example.firstproject.entity.Article;
import com.example.firstproject.repository.ArticleRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Slf4j  // 로그 찍을 수 있게
@RestController     // REST 컨트롤러 선언
public class ArticleApiController {
    @Autowired
    private ArticleRepository articleRepository;
    // GET
    @GetMapping("/api/articles")    // 전체 데이터 조회
    public List<Article> index(){
        return articleRepository.findAll();
    }

    @GetMapping("/api/articles/{id}")
    public Article show(@PathVariable Long id){
        return articleRepository.findById(id).orElse(null);
    }

    // POST
    @PostMapping("/api/articles")
    public Article create(@RequestBody ArticleForm dto){
        Article article=dto.toEntity();
        return articleRepository.save(article);
    }

    // PATCH

    @PatchMapping("/api/articles/{id}")
    public ResponseEntity<Article> update(@PathVariable Long id, @RequestBody ArticleForm dto){
        // 1. DTO->엔티티 변환
        Article article=dto.toEntity(); // dto를 엔티티로 변환. article : 수정할 데이터
        log.info("id: {}, article: {}",id,article.toString());  // 로그 찍기
        // 2. 타깃 조회
        Article target=articleRepository.findById(id).orElse(null); // target : 기존 데이터
        // 3. 잘못된 요청 처리
        if(target==null||id!=article.getId()){
            // 400, 잘못된 요청 응답!
            log.info("잘못된 요청! id: {}, article: {}",id,article.toString());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
        }
        // 4. 업데이트 및 정상 응답(200)하기
        target.patch(article);      // 기존 데이터에 새 데이터 붙이기
        Article updated=articleRepository.save(target);    // 수정 내용 DB에 최종 저장
        return ResponseEntity.status(HttpStatus.OK).body(updated);
    }

    //DELETE
    @DeleteMapping("/api/articles/{id}")
    public ResponseEntity<Article> delete(@PathVariable Long id){
        // 1. 대상 찾기
        Article target=articleRepository.findById(id).orElse(null);
        // 2. 잘못된 요청 처리하기
        if(target==null){
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
        }
        // 3. 대상 삭제하기
        articleRepository.delete(target);
        return ResponseEntity.status(HttpStatus.OK).build();    // build()는 HTTP 응답의 body가 없는 ResponseEntity 객체 생성. body(null)과 같음
    }
}

 

ResponseEntity는 REST 컨트롤러의 반환형으로 REST API 응답을 위해 사용하는 클래스임.

REST API 요청을 받아 응답할 때 이 클래스에 HTTP 상태 코드, 헤더, 본문을 실어 보낼 수 있음.

 

HttpStatus란 HTTP 상태 코드를 관리하는 클래스. 상태 코드 200은 HttpStatus.OK, 201은 HttpStatus.CREATED, 400은 HttpStatus.BAD_REQUEST 등으로 관리