스프링부트

REST PUT vs PATCH

알쓸개잡 2023. 10. 22.

Spring REST 서비스 예제를 통해서 HTTP PUT과 HTTP PATCH 요청 메서드에 대한 차이점에 대해서 알아보자.

 

HTTP PUT vs PATCH

PUT과 PATCH는 모두 요청 URI로 표시된 리소스를 수정하는 데 사용되지만 약간의 차이점이 있다.

 

HTTP PUT 요청 메서드

  • 새 리소스를 생성하거나 대상 리소스를 요청 페이로드에 제공된 리소스로 대체된다.
  • 멱등성이 유지되어 사용자가 같은 요청을 반복해도 동일한 결과를 얻는다.
  • PUT 요청의 전제 조건은 요청 본문에 리소스에 대한 완전한 데이터를 보내는 것이다.
  • 리소스를 부분적으로 수정하려는 경우라도 수정되지 않는 나머지 필드를 모두 포함시킨다.
  • 요청에 변경되지 않는 필드가 포함되어 있지 않은 필드는 서버에서 null 값을 채운다.

HTTP PATCH 요청 메서드

  • 대상 리소스에 대한 부분적인 수정을 적용한다.
  • 리소스 상태에 따라서 멱등성이 적용될 수도 안될 수도 있다.
  • PATCH 요청의 전제 조건은 리소스가 서버에 이미 존재해야 한다는 것이다.
  • 요청 본문에 수정이 필요한 필드만 제공한다.
  • 제공된 필드에 대해서만 수정하고 나머지 필드를 변경하지 않는 것은 서버의 책임이다.

 

Example

API는 StudentDto를 request body로 입력받아 Student 엔티티로 변환 후 DB에 저장 처리한다.

PUT

@PutMapping("/students/{id}")
public void putStudent(
        @PathVariable long id, 
        @RequestBody StudentDto studentDto) {

    Student student = new Student();
    student.setStudent_id(id);
    student.setFirstName(studentDto.getFirstName());
    student.setLastName(studentDto.getLastName());
    student.setYear(studentDto.getYear());
    studentRepository.save(student);
}

@PathVariable을 통해서 Student 엔티티에 대한 id를 읽고 요청 본문은 StudentDto에 매핑된다.

id필드를 설정하여 Student 엔티티를 생성하여 StudentDto 필드의 값을 Student 엔티티에 채운다.

studentRepository.save(student)를 통해서 생성(없는 경우) 혹은 업데이트(있는 경우)를 한다.

 

PATCH

@PatchMapping("/students/{id}")
public void patchResource(
        @PathVariable long id, 
        @RequestBody StudentDto studentDto) {
        
    Student student = studentRepository
            .findById(id).orElseThrow(StudentNotFoundException::new);

    boolean needUpdate = false;

    if (StringUtils.hasLength(studentDto.getFirstName())) {
        student.setFirstName(studentDto.getFirstName());
        needUpdate = true;
    }

    if (StringUtils.hasLength(studentDto.getLastName())) {
        student.setLastName(studentDto.getLastName());
        needUpdate = true;
    }

    if (studentDto.getYear() > 0) {
        student.setYear(studentDto.getYear());
        needUpdate = true;
    }

    if (needUpdate) {
        studentRepository.save(student);
    }
}

PATCH 요청 메서드의 시그니처는 PUT과 동일하지만, 요청 본문에 모든 필드가 포함되지 않을 수 있다.

PUT과 동일하게 @PathVariable을 통해서 Student 엔티티에 대한 id를 읽고 요청 본문은 StudentDto에 매핑된다.

id에 해당하는 Student 엔티티를 DB에서 먼저 조회를 하고 존재하지 않으면 예외를 발생시킨다.

StudentDto에서 각 필드 유무를 확인하고 필드가 있는 경우 해당 필드만 변경하여 DB에 저장한다.

댓글

💲 추천 글