본문 바로가기
스터디/Spring

[Spring] PUT 과 PATCH 사용시 주의할 점

by zoodi 2024. 7. 6.
728x90

목차

     

     

     

    1. Spring 에서 PUT 과 PATCH 사용 시 발생하는 이슈

    일반적으로 PUT은 전체 수정, PATCH 는 일부 필드 수정으로 이해하고 사용하고있습니다.

    Spring 을 사용하면서 해당 Http Method 를 사용하다가 이슈가 발생한 경험이있는데요, 어떤 이슈가 있었고 어떻게 해결하는지 알아보겠습니다.

     

     

    2. PUT method

    예시 코드

    class TestController {
    
       @PutMapping("/test/put")
    	public void putSample( @RequestBody Task task) {
    		System.out.println(task);
    	}
    }
    
    class Task {
      private String title;
      private String content;
    
      ...
    }

     

     

    Request & Result

    {
        "title": "this is title",
        "content" : "this is content"
    }
    //Task{title='this is title', content='this is content'}
    
    {
        "title": "this is title",
    }
    //Task{title='this is title', content='null'}
    
    
    {
        "title": "this is title",
        "content" : null
    }
    //Task{title='this is title', content='null'}
    • PUT 메소드는 content 필드를 보내지 않으면 null 값으로 적용됩니다.

     

     

    3. PATCH method

    예시 코드

    class TestController {
    
       @PatchMapping("/test/patch")
    	public void putSample( @RequestBody Task task) {
    		System.out.println(task);
    	}
    }
    
    class Task {
      private String title;
      private String content;
    
      ...
    }

     

    Request & Result

    {
        "title": "this is title",
        "content" : "this is content"
    }
    //Task{title='this is title', content='this is content'}
    
    {
        "title": "this is title",
    }
    //Task{title='this is title', content='null'}
    //여기서 이슈 발생
    //원하는 시나리오는 content는 기존값을 유지하고 title만 변경하는 것인데 content=null 로 업데이트가 될 수 있다.
    
    {
        "title": "this is title",
        "content" : null
    }
    //Task{title='this is title', content='null'}
    • PATCH 메소드를 사용할 경우 Request에 content 필드를 보내지 않으면 기대 결과는 content는 기존값 유지, title만 변경되는 것입니다.
    • 하지만 실제로 content = null 로 변경이됩니다.

     

    4. JsonNullable 관련 설정 추가

    여기서 문제는 Spring Boot 기반의 기본 프로젝트 구성으로는 특정 필드를 null로 교체하라는 것인지, 교체 대상이 아니라는 것인지 식별할 수 있는 방법이 없다는 것입니다.

    이러한 이슈를 해결하기위해 Jackson 기반의 모듈인 JsonNullable 관련 설정을 추가해줍니다.

     

    - build.gradle

    dependencies {
    	implementation 'org.springframework.boot:spring-boot-starter-web'
    	testImplementation 'org.springframework.boot:spring-boot-starter-test'
    	implementation("org.openapitools:jackson-databind-nullable:0.2.4")   // 의존성 추가
    }

     

    - Todo.java

    public class Todo {
    	private JsonNullable<String> title;
    	private JsonNullable<String> content;
    	...
    }

     

    - Controller

    @PatchMapping("/test/patch")
    	public void patchSample( @RequestBody Todo todo) {
    		System.out.println(task);
    		if (todo.getTitle().isPresent()) {
    			System.out.println("todo title 존재: " + todo.getTitle());
    		}
    		if (todo.getContent().isPresent()) {
    			System.out.println("todo content 존재: " + todo.getContent());
    		}
    	}

     

    - Request

    {
        "title": "this is title"
    }
    
    Todo{title='JsonNullable[this is title]', content='JsonNullable.undefined'}
    todo title 존재: JsonNullable[this is title]

     

    {
        "title": "this is title",
        "content": null
    }
    Todo{title='JsonNullable[this is title]', content='JsonNullable[null]'}
    todo title 존재: JsonNullable[this is title]
    todo content 존재: JsonNullable[null]
    • JsonNullable 을 적용하면 content 필드를 보내지 않을 경우 undefined 로, null 로 보내면 null 로 요청이 들어옵니다.

    <참고자료>

    728x90

    댓글