Article - 깊게 탐구하기/핀잇 일지
[Pinit] HTTP Patch의 구현 방식
조금씩 차근차근
2025. 11. 11. 23:34
Get과 Post는 구현 방식이 비교적 단순하지만, Patch의 경우 몇가지 고려해야 할 점이 있다.
여기서 외부 라이브러리 사용은 자제하고 싶었다.
- 외부 라이브러리의 변경으로 인한 버그와 같은 문제는 피하고 싶었다.
그렇다면 이제 Patch를 구현하기 위해, Patch의 요구사항을 살펴보자.
HTTP Patch 메소드
- 데이터의 부분 업데이트를 요청한다.
- PUT과 달리 멱등성을 보장하지 않는다.
- 캐시가 가능하지만, 본문까지 캐시 키로 봐야 해서 일반적으로 잘 쓰이지 않는다.
Patch의 경우, 프론트와 백 중 한 곳에서 "어디에서 변경이 발생했는가"를 확인하는 작업이 필요하다.
- 프론트가 편하게 만들 경우, 백엔드에서 뭐가 변경되었는지 명확히 알지 못하는 문제가 존재한다.
- 그렇다고 각 수정 내용을 하나씩 Post 메소드로 호출하게 하는 것은 프론트의 개발비용적으로 비효율적이다.
- 그렇다고 엔티티를 put 메소드처럼 바로 merge 하게 되면, DTO에 없는 필드가 null로 복사되어 기존 값이 소거될 수 있다.
- 따라서 프론트에서 보내줄 때는 변경된 부분만을 전달하고, 백엔드는 그 부분만을 선택적으로 업데이트 하는 방식을 사용한다.
그렇다면 어떤 방식으로 구현하는 것이 좋을까?
나는 두 가지 방식을 고려했다.
1안: 변경 내용 문자열로 받기

이 방식의 경우, 추가적인 도메인 로직의 확장 없이 patch 로직을 백엔드에서 구현할 수 있다.
하지만 위에서 보듯이 switch expression 을 사용해야 한다.
이는 애플리케이션 레이어에서 "어떻게" 동작할 것인지를 정의해야 하는, 명령형 프로그래밍 방식이 적용됨을 의미한다.
2안: Patch 수정 자체를 도메인 로직으로 보고, 도메인 레이어에 커맨드 객체 추가하기

Patch 수정 자체를 도메인 로직으로 본다면, 애플리케이션 레이어에서는 위와 같이 선언형 방식으로 동작이 가능해진다.
이를 위해선 아래와 같은 "Patch 객체" 가 필요해지는데, 이는 아래와 같다.

특정 값이 null 값을 가질 수 있기 때문에, Builder 패턴처럼 객체 내 필드를 추가하는 형태를 적용했다.
그러면 Schedule 엔티티에 Patch 객체를 활용하는 메소드를 추가할 수 있다.

이는 명령형이 아닌 선언형 프로그래밍 방식으로, 귀찮은 조건 과정을 생각할 필요가 없어저 훨씬 가독성이 좋은 코드가 탄생한다.
- 복잡한 switch-case / 조건문 없음
- 수정 방식 또한 도메인 로직으로 볼 수 있다고 판단
- 명령형보단 선언형 프로그래밍 방식이 코드 가독성이 더 뛰어나다고 판단
- 애플리케이션 서비스 레이어에 조건문 없음. 도메인 레이어에서 도메인 로직에 집중
따라서 위와 같은 2안을 선택하였다.