Get-and-Patch

“Get-and-Patch"는 리소스의 부분적 업데이트를 효율적으로 처리하기 위한 REST API 디자인 패턴으로, 기존 CRUD(Create, Read, Update, Delete) 방식의 한계를 보완한다.
이 패턴은 GET과 PATCH 메서드 조합을 통해 리소스의 전체 상태를 검색하지 않고도 특정 필드만 업데이트할 수 있도록 설계되었다.

핵심 개념

두 단계 프로세스

  1. Get: 리소스의 현재 상태 조회 (필요한 필드 확인)
  2. Patch: 변경된 필드만 서버에 전송하여 부분 업데이트

HTTP 메서드 활용

단계HTTP 메서드설명
GetGET리소스의 전체/일부 상태 조회
PatchPATCH식별된 필드만 부분적으로 업데이트

CRUD vs. Get-and-Patch

구분CRUD (PUT)Get-and-Patch (PATCH)
업데이트 범위전체 리소스 교체특정 필드만 수정
네트워크 효율성모든 필드 전송 필요변경된 필드만 전송
멱등성보장됨조건부 보장 (구현 방식에 따라 다름)
동시성 제어전체 리소스 버전 관리필드 단위 낙관적 잠금 가능
사용 사례단순 리소스 교체대규모 객체의 일부 수정

작동 원리

Get 단계

  • 클라이언트가 리소스의 현재 상태를 조회한다.

  • 예시: 사용자 프로필의 email 필드 확인

    1
    
    GET /users/123
    

Patch 단계

  • 변경할 필드만 선택적으로 서버에 전송한다.
  • 예시: email 필드 업데이트
1
2
3
4
5
6
  PATCH /users/123
  Content-Type: application/json-patch+json

  [
    { "op": "replace", "path": "/email", "value": "new@example.com" }
  ]

주요 장점

  1. 네트워크 효율성

    • 전체 리소스 대신 변경된 데이터만 전송.
    • 대용량 리소스(예: 100개 필드)에서 1개 필드 수정 시 99% 대역폭 절약.
  2. 동시성 충돌 감소

    • 필드 단위 업데이트로 다른 클라이언트의 병렬 수정 가능.
  3. 유연한 스키마 관리

    • 스키마 변경 없이 새 필드 추가/삭제 가능.
  4. 안정성

    • 부분 실패 시 전체 롤백 대신 해당 필드만 재시도 가능.

구현 방식

JSON Patch 형식 (RFC 6902)

1
2
3
4
[
  { "op": "replace", "path": "/name", "value": "John" },
  { "op": "remove", "path": "/oldField" }
]

부분 리소스 업데이트

1
2
3
4
{
  "email": "updated@example.com",
  "preferences": { "theme": "dark" }
}

고급 활용 전략

낙관적 동시성 제어

  • ETag/버전 번호를 이용한 충돌 방지:
1
2
  PATCH /users/123
  If-Match: "a1b2c3d4"

배치 처리

  • 여러 필드를 단일 요청으로 처리:
1
2
3
4
5
PATCH /users/123
[
{ "op": "replace", "path": "/email", "value": "new@example.com" },
{ "op": "add", "path": "/phone", "value": "+821012345678" }
]

감사 로깅

  • 변경 이력을 필드 단위로 기록:
1
2025-03-22 21:15:00 | User 123 | email: old@ → new@example.com

주의사항

  1. 멱등성 보장

    • PATCH는 기본적으로 멱등성이 없으나, JSON Patch 형식을 사용하면 멱등성 보장 가능.
  2. 부분 업데이트 오류

    • 존재하지 않는 필드 수정 시 400 Bad Request 반환 필요.
  3. 보안 검증

    • 허용되지 않은 필드(예: role) 업데이트 시 권한 검증 필수.

사용 사례

  1. 대규모 설정 관리

    • 50개 이상의 설정 필드 중 1~2개 필드만 빈번히 업데이트
  2. 실시간 협업 편집

    • Google Docs 스타일 협업 시스템
  3. IoT 장치 상태 모니터링

    • 센서 데이터의 특정 지표(온도/압력)만 주기적 업데이트

코드 예시 (Node.js/Express)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// GET: 리소스 조회
app.get('/users/:id', async (req, res) => {
  const user = await User.findById(req.params.id);
  res.json(user);
});

// PATCH: 부분 업데이트
app.patch('/users/:id', async (req, res) => {
  try {
    const updates = req.body;
    const user = await User.findByIdAndUpdate(
      req.params.id,
      { $set: updates },
      { new: true, runValidators: true }
    );
    res.json(user);
  } catch (error) {
    res.status(400).json({
      type: "https://api.example.com/errors/invalid-input",
      title: "Invalid Update",
      detail: error.message
    });
  }
});

용어 정리

용어설명

참고 및 출처