스프링 부트, 입문! 19

윤현우·2022년 12월 2일
0

스프링 부트, 입문!

목록 보기
16/18
post-thumbnail

RestController 와 HTTP

오늘은 ResController를 이용하여 데이터의 CRUD처리를 배워볼 것이다.

RestController란 서버와 DB의 데이터 이동을 위해 만들어진 Controller로 일반 Controller는 뷰페이지와 연결이 되지만, RestController는 JSON(데이터)을 반환하는 RestAPI Controller이다.

RestController 에서는 GET, POST, PATCH, UPDATE, DELETE 등의 메서드를 사용할 수 있다.


RestController

RestController를 작성하여 연습해보았다.

ArticleApiController.java

package com.example.springstudy.api;

import com.example.springstudy.entity.Article;
import com.example.springstudy.dto.ArticleForm;
import com.example.springstudy.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;
import java.util.Scanner;

@RestController
@Slf4j
public class ArticleApiController {

    @Autowired  // DI 외부에서 가져온다. (의존관계 주입)
    private ArticleRepository articleRepository;

    // GET

    // 게시글 페이지 (메인 페이지)
    @GetMapping("/api/articles")
    public List<Article> index() {
        return articleRepository.findAll(); 
    }

    // 게시글 상세 페이지
    @GetMapping("/api/articles/{id}")
    public Article index(@PathVariable Long id) {
        return articleRepository.findById(id).orElse(null);
    }

    // POST (게시글 추가)
    @PostMapping("/api/articles")
    public Article create(@RequestBody ArticleForm dto) {   // @RequestBody -> JSON 데이터 받기
        Article article = dto.toEntity();
        return articleRepository.save(article);
    }

    // PATCH (게시글 수정)
    @PatchMapping("/api/articles/{id}")
    public ResponseEntity<Article> edit(@PathVariable Long id, @RequestBody ArticleForm dto){  
    // Article을 담아서 ResponseEntity로 리턴 값을 보내야 한다. 그래야 응답 코드를 반환할 수 있다.
    // ResponseEntity에 Article이 담겨서 JSON으로 반환이 된다.

        // 1. 수정용 Entity 생성
        Article article = dto.toEntity();

        // 2. 대상 Entity 조회
        Article target = articleRepository.findById(id).orElse(null);

        // 3. 잘못된 요청 처리(대상이 없거나, id가 없는경우)
        if( target != null || id != target.getId()) {
            // 400 요청, 잘못된 응답 요청!
            log.info("잘못된 응답 요청! id: {}, articles: {}", id, article.toString());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);   // BAD_REQUEST = 400번 코드 반환
        }

        // 4. 업데이트 및 정상 응답(200)
        target.patch(article);
        Article updated = articleRepository.save(target);
        return ResponseEntity.status(HttpStatus.OK).body(updated);
    }

    // DELETE
    @DeleteMapping("/api/articles/{id}")
    public ResponseEntity<Article> delete(@PathVariable Long id){
        // 대상 Entity 조회
        Article target = articleRepository.findById(id).orElse(null);

        // 대상 Entity 삭제
        // 대상 Entity 가 null일 경우 400번 오류 코드 반환
        if(target == null) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);   // BAD_REQUEST = 400번 코드 반환
        }

        // 데이터 반환
        articleRepository.delete(target);
        return ResponseEntity.status(HttpStatus.OK).build();
    }
}

GET 메서드

	// 게시글 페이지 (메인 페이지)
    @GetMapping("/api/articles")
    public List<Article> index() {
        return articleRepository.findAll(); 
    }

    // 게시글 상세 페이지
    @GetMapping("/api/articles/{id}")
    public Article index(@PathVariable Long id) {
        return articleRepository.findById(id).orElse(null);
    }

public List<Article> index()

  • 게시글 목록을 요청하는 메서드로 Entity클래스인 Article을 리스트로 반환한다.

@PathVariable Long id

  • GetMapping할 주소에 {id}값이 있는데 그 id 값을 변수로 사용하는 어노테이션

articleRepository.findById(id).orElse(null);

  • articleRepository에 있는 findById함수를 사용하여 해당 id의 데이터를 반환하는 메서드
  • orElse(null)은 만약 해당 아이디의 값이 없다면 null을 반환한다.

POST 메서드

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

public Article create(@RequestBody ArticleForm dto)

  • @RequestBody -> JSON 데이터를 받는 어노테이션
  • "/api/articles" http 주소에서 받은 데이터는 ArticleForm이라는 dto 클래스로 받아와진다.

Article article = dto.toEntity();

  • dto로 받아와진 데이터를 Entity로 변환

return articleRepository.save(article);

  • Entity로 변환된 데이터를 Repository클래스를 통해 저장

PATCH 메서드

	// PATCH (게시글 수정)
    @PatchMapping("/api/articles/{id}")
    public ResponseEntity<Article> edit(@PathVariable Long id, @RequestBody ArticleForm dto){  
    // Article을 담아서 ResponseEntity로 리턴 값을 보내야 한다. 그래야 응답 코드를 반환할 수 있다.
    // ResponseEntity에 Article이 담겨서 JSON으로 반환이 된다.

        // 1. 수정용 Entity 생성
        Article article = dto.toEntity();

        // 2. 대상 Entity 조회
        Article target = articleRepository.findById(id).orElse(null);

        // 3. 잘못된 요청 처리(대상이 없거나, id가 없는경우)
        if( target != null || id != target.getId()) {
            // 400 요청, 잘못된 응답 요청!
            log.info("잘못된 응답 요청! id: {}, articles: {}", id, article.toString());
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);   // BAD_REQUEST = 400번 코드 반환
        } 
        // 4. 업데이트 및 정상 응답(200)
        target.patch(article);
        Article updated = articleRepository.save(target);
        return ResponseEntity.status(HttpStatus.OK).body(updated);
    }

@PatchMapping("/api/articles/{id}")

  • 게시글 수정 매핑

public ResponseEntity<Articles> edit(@PathVariable Long id, @RequestBody articleForm dto)

  • ResponseEntity는 상태코드를 반환 시켜주는 클래스이다.(자세한 내용은 뒤에)
  • @RequestBody 어노테이션은 JSON(데이터)를 받는 어노테이션

return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);

  • BAD_REQUEST = 400 오류 코드
  • 400번 오류 코드를 반환시키는 ResponseEntity 메서드
  • .body(null); -> HttpRequest의 body 부분에 null값을 넣는다.

target.patch(article)

  • 해당 Entity를 수정하게 하는 메서드 (Entity 클래스에 patch메서드 필요함)

Article.java(Entity 클래스)

	// patch 요청 받은 함수 ( article의 title이나 content가 null값이 아니라면 Entity에 값을 넣어준다.)
    public void patch(Article article) {
        if (article.title != null)
            this.title = article.title;
        if(article.content != null)
            this.content = article.content;
    }

DELETE 메서드

	// DELETE
    @DeleteMapping("/api/articles/{id}")
    public ResponseEntity<Article> delete(@PathVariable Long id){
        // 대상 Entity 조회
        Article target = articleRepository.findById(id).orElse(null);

        // 대상 Entity 가 null일 경우 400번 오류 코드 반환
        if(target == null) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);   // BAD_REQUEST = 400번 코드 반환
        }

        // 데이터 삭제 및 반환
        articleRepository.delete(target);
        return ResponseEntity.status(HttpStatus.OK).build();
    }

if(target == null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}

  • 데이터가 null이면 오류 코드를 반환하는 메서드 사용

return ResponseEntity.status(HttpStatus.OK).build();

  • 200번 성공 코드 반환

ResponseEntity란

ResponseEntity란, HttpEntity를 상속받는, 결과 데이터와 HTTP 상태 코드를 직접 제어할 수 있는 클래스이다.

ResponseEntity에는 사용자의 HttpRequest에 대한 응답 데이터가 포함된다.

에러 코드와 같은 HTTP상태 코드를 전송하고 싶은 데이터와 함께 전송할 수 있기 때문에 좀 더 세밀한 제어가 필요한 경우 사용한다고 합니다.

  • 반환 타입에서 사용할 수 있다.
    ex)
public ResponseEntity<Article> save(){

}

라는 메서드가 있을 때, Article이라는 데이터를 담아서 해당 데이터에 대한 오류 코드와 데이터를 반환할 수 있다.

  • API 개발 시 올바른 상태코드를 응답하는 것은 매우 중요하다
    -> 클라이언트가 어느 부분에서 잘못 입력을 했는지 알려줄 수 있기 때문에 반환값을 상태 코드 값으로 만들면 좋다.

    상태 코드를 반환하기 위해서는 ResponseEntity를 사용하여 반환한다.


References (참고 자료)
https://www.inflearn.com/course/%EA%B0%9C%EB%85%90%EC%8B%A4%EC%8A%B5-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8-
https://thalals.tistory.com/268

profile
개발자가 되는 그날까지

0개의 댓글