코딩 공부/Spirngboot

[RESTAPI] 따라하기

sintory-04 2025. 1. 15. 21:54

1. REST API

- 서버 자원을 클라이언트에 구애받지 않고 사용할 수 있게 하는 설계 방식.

- 클라이언트에서 정보를 요청하면 서버는 특정 기기에 종속되지 않고 모든 기기에서 통용할 수 있는 JSON 데이터를 응답 보냄.

서버는 클라이언트의 요청에 대한 응답으로 View가 아닌 Data를 전송함. 이때 사용하는 응답데이터가 JSON임.


2. RestController

- RestController는 HTTP 요청을 처리하고 JSON과 같은 데이터 형식으로 응답을 반환함.

- 클라이언트가 요청 > 매핑된 메서드로 전달 > 서비스 로직 처리 > 응답 반환 

 

여기서 의문이 생긴다. Controller와는 무슨 차이가 있느냐? 이다.

그래서 Rest Controller 와 Controller 에 대한 차이를 알아보겠다.

1. Controller

- 사용자가 브라우저를 통해 보낸 데이터를 받아 > 이를 서버에서 처리 > 뷰페이지 를 반환.

= 엔티티 객체로부터 ID를 추출하여 URL 생성이나 뷰 리다이렉트에 사용

그러니까 HTML 페이지를 제공해주는 것

2. RestController

- 클라이언트- 서버 간 데이터 통신에 초점.

- 클라이언트가 이미 요청 경로에 ID를 포함하여 보냈으므로, URL에서 전달된 id를 바로 사용합니다.

그러니까 API를 제공해주는 것이다.(데이터 주고받는 통로)


3. RESTAPI 실습 내용

RestAPI의 주요 URL은 4가지다.

GET, POST, PATCH, DELETE

1) GET 조회 -  /api/articles 혹은 api/articles/{id}

@RestController
public class ArticleApiController {
  @Autowired
  private ArticleRepository articleRepository;
  //Get
  // 1. 리스트 조회
  @GetMapping("/api/articles")
  public List<Article> index(){
    return articleRepository.findAll();
  }
  // 2. 단일 게시물 조회
  @GetMapping("/api/articles/{id}")
  public Article show(@PathVariable Long id){
    return articleRepository.findById(id).orElse(null);
  }

2) POST 생성 - api/articles

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

3) PATCH 수정 - api/articles/{id}

수정용 엔티티 생성 > DB에 엔티티 있는지 조회 > 대상 엔티티 없거나 수정하려는 id가 잘못됐을 경우 처리 > 대상 엔티티가 있으면 수정 내용으로 업데이트하고 정상응답 보내기.

여기서 위에서 언급했던 Controller 와의 차이를 상기해야한다.

Controller - update RestController - update
폼에서 사용자가 수정할 데이터를 전송
클라이언트(브라우저)는 모든 데이터를 폼 데이터로 서버에 보냄
서버는 이를 DTO 객체로 받음
데이터 수정이 완료되면 사용자에게 View 페이지 리다이렉트
REST API를 통해 클라이언트는 JSON 데이터를 서버에 보냄
JSON 데이터는 수정할 데이터가 모두 포함.
데이터를 서버가 바로 처리
서버는 수정된 결과를 JSON으로 반환 
REST API 요청에서는 클라이언트가 URL 경로로 ID 전달, 요청 본문으로 수정할 데이터 전달

 

RestController의 JSON 요청은 수정할 데이터를 모두 포함된다.

따라서 요청 본문에 포함된 ID(JSON 데이터 안의 ID)가 기존에 Repository에 저장된 ID와 같은지

확인하는 과정이 필요하다.

이는 데이터 일관성을 유지하고, 의도하지 않은 데이터 변경을 방지하기 위해 중요하다.

Check 해야할 부분이 target이 null인지, 요청 본문의 id가 기존 id와 같은지를 확인해야한다!

  @PatchMapping("/api/articles/{id}")
  public ResponseEntity<Article> update(@PathVariable Long id, @RequestBody ArticleForm dto){
    // 1. DTO를 ENTITY로 변환
    Article article = dto.toEntity();
    // 2. 타깃 조회하기
    Article target = articleRepository.findById(id).orElse(null);
    // 3. 잘못된 요청 처리하기
    if (target == null || id != article.getId()){
      // 잘못된 요청 응답
      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);
    return ResponseEntity.status(HttpStatus.OK).body(updated);
  }

PATCH에 대한 부분도 필요하다.

Entity 에 patch() 추가 할것이다.

  public void patch(Article article) {
    if (article.title != null)
      this.title = article.title;
    if (article.content != null)
      this.content = article.content;
  }

 

4) DELETE 삭제 - api/articles/{id}

  @DeleteMapping("/api/article/{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).body(null);
  }