2016-06-29 12 views
0

정기적으로 목록 업데이트를받을 웹 서비스를 설계하고 있습니다. 이 시점에서 목록은 여전히 ​​단일 엔터티 (/lists/myList) 또는 많은 리소스가 포함 된 실제 모음 (/lists/myList/entries/<ID>)으로 모델링 될 수 있습니다. 목록은 크고 (수백만 개의 항목) 업데이트가 적습니다 (종종 10 개 미만의 변경 사항).HTTP ReST : 대규모 콜렉션 업데이트 : JSON PATCH보다 나은 접근법?

배포 할 웹 서비스 URL 및 목록을 얻을 것이다 클라이언트, 예를 들면 :

그러면 목록 및 업데이트가 구성된대로 푸시됩니다. 웹 서비스 URL 뒤에 데이터베이스가있는 경우에는 가능성이 있지만 결정되지 않습니다.

저는 연구 중이며 HTTP 패치가 JSON 패치 형식을 사용하는 것이 가장 좋은 방법이라고 생각합니다.

컨텍스트 및 예 : 각 목록에는 식별 이름, 우선 순위 및 수백만 개의 항목이 있습니다. 각 항목에는 ID (클라이언트가 결정한)와 몇 가지 선택적 속성이 있습니다. 예 우선 순위 1 개의 목록 항목이 목록 "requiredItems"를 만들 수 있습니다 :

PUT /lists/requiredItems 
Content-Type: application/json 


{ 
    "priority": 1, 
    "entries": { 
    "1": { 
     "color": "red", 
     "validUntil": "2016-06-29T08:45:00Z" 
    }, 
    "2": { 
     "country": "US" 
    } 
    } 
} 

업데이트의 경우, 클라이언트는 먼저 목록이 서버에 지금 어떻게 생겼는지 알고 있어야합니다. 이를 위해 목록 엔티티에 속성 "개정"을 추가합니다.

그럼,이 속성을 조회 할 것이다 :

GET /lists/requiredItems?property=revision 

그런 다음 클라이언트가 서버의 개정 및 클라이언트에 의해 알려진 최신 버전 사이에 변경하고 JSON 패치를 구성 할 필요가 무엇을 볼 것입니다. 예 :

PATCH /list/requiredItems 
Content-Type: application/json-patch+json 

[ 
    { "op": "test", "path": "revision", "value": 3 }, 
    { "op": "add", "path": "entries/3", "value": { "color": "blue" } }, 
    { "op": "remove", "path": "entries/1" }, 
    { "op": "remove", "path": "entries/2/country" }, 
    { "op": "add", "path": "entries/2/color", "value": "green" }, 
    { "op": "replace", "path": "revision", "value": 10 } 
] 

질문 :

  • 이러한 접근 방식은 약간 덜 클라이언트 지원의 단점이 때문에하지-자주 사용되는 HTTP 동사의 패치. HTTP 호환성을 떨어 뜨리지 않으면 서 호환 가능한 접근 방식이 있습니까? (idempotency et cetera)? 모든 작업이 적용
  • 별도의 리소스로 개별 목록 항목을 모델링하고 (ETag 및/또는 If-Match와 아마) PUTDELETE를 사용은 옵션 (PUT /lists/requiredItems/entries/3, DELETE /lists/requiredItems/entries/1PUT /lists/requiredItems/revision)을 보이지만, 어떻게 내가 확인 할 때 네트워크 방울을 업데이트 체인의 중간에? HTTP PATCH가 여러 리소스에서 작동 할 수 있습니까?
  • 목록을 '버전 화'하는 더 좋은 방법이 있습니까? 아마도 암시 적으로 어떻게 업데이트되어 업데이트 될까요? 클라이언트는 개정 번호를 결정합니다.
  • GET /lists/requiredItems?property=revision으로 수정 번호를 쿼리하는 것이 맞습니까? /lists/requiredItems/revision과 같은 별도의 리소스 여야합니까? 별도의 리소스 여야하는 경우이를 어떻게 자동으로 업데이트합니까 (예 : 목록 및 수정 버전이 모두 업데이트되었거나 업데이트되지 않은 경우)?
  • JSON 패치에서 수정 값을 먼저 테스트하여 3이되도록하고 같은 패치에서 10으로 업데이트 하시겠습니까?
+0

한 번에 두 가지 이상의 질문을하지 마십시오. 그들 모두는 유효하지만 아마도 그들 모두에 대한 대답을 얻지 못할 것입니다. –

+0

@LutzHorn : 감사합니다. 당신 말이 맞아요. 한 가지 질문 만 제외하고 나머지는 별도로 다시 게시해야합니까? 소개 부분은 동일합니다 ... –

답변

2

이 접근법에는 자주 사용되지 않는 HTTP 동사 PATCH로 인해 클라이언트 지원이 약간 줄어드는 단점이 있습니다.

내가 알 수있는 한, 귀하의 서버가 "다음 설명에 따라 문서 사본을 업데이트하십시오."라는 바보 같은 문서 저장소처럼 작동하는 경우에만 적용됩니다.

리소스가 실제로 수백만 개의 항목이있는 목록을 설명하는 JSON 문서 인 경우 JSON-Patch는 훌륭한 대답입니다.

그러나 패치가 부작용으로 도메인의 엔티티를 업데이트 할 것으로 예상되는 경우 의심 스럽습니다.

HTTP 패치가 여러 리소스에서 작동 할 수 있습니까?

나는 질의에 치열하지 않다

RFC 5789

패치 방법은 Request-URI가 식별하는 자원에 영향을 미치는, 또한 다른 자원에 대한 부작용이있을 수 있습니다 개정 번호; ETag/If-Match 방식을 사용하는 것보다 명확한 이점이없는 것처럼 보입니다. 몇 가지 명백한 단점 - 사용자와 클라이언트 간의 캐시는 목록과 버전 번호가 관련되어 있다는 것을 모릅니다. 캐시는 목록의 버전 12가 버전 7임을 클라이언트에게 행복하게 알려주거나 반대의 경우도 마찬가지입니다.

+0

고마워! 웹 서비스에는 데이터베이스가있을 수도 있고 없을 수도 있습니다. 나는 클라이언트와 웹 서비스를 설계하고 있지만 서버 측은 설계하지 않았다. 서버 측은 몇 가지 다른 제 3 자 구현이 될 것입니다. 질문의 시작 부분에 몇 가지 설명을 추가했습니다. –

+0

/service/list1에 대한 패치가 다른 리소스에 영향을 줄 수있는 경우 HTTP가 캐싱을 활성화하는 방법을 이해하지 못합니다. PATCH가 요청 될 때마다 전체 캐시를 무효화하십시오. –

+0

PATCH에 공평성이 있음에도 POST, PUT, DELETE와 같은 문제가 발생합니다. 캐시 일관성은 두 가지 어려운 문제 중 하나입니다. – VoiceOfUnreason

0

내 질문에 답하는 중입니다. 내 첫 번째 글 머리 포인트는 의견을 기반으로 할 수 있으며, 지적했듯이 한 가지 게시물에서 많은 질문을했습니다. 그럼에도 불구하고 다른 사람들 (VoiceOfUnreason)이 대답 한 내용과 내 자신의 추가 조사 내용을 요약하면 다음과 같습니다.

ETags는 HTTP의 리소스 인 '해시'입니다. If-Match 헤더와 함께 버전 관리 시스템을 사용할 수 있습니다. 그러나 ETag 헤더는 일반적으로 생성 (PUT) 또는 업데이트 (POST/PATCH)중인 리소스의 ETag를 선언하는 데 사용되지 않습니다. 리소스를 저장하는 서버는 대개 ETag를 결정합니다. 나는 명시 적으로 이것을 금지하는 것을 찾지 못했지만 많은 구현은 서버가 PUT 또는 PATCH와 함께 제공 될 때 ETag를 결정하고 혼란스러워한다고 가정 할 수 있습니다.

별도의 개정 자원은 버전 관리를위한 ETags 대신 유효한 대체 자원입니다. 이 자원은 개정판의 자원과 동시에 갱신되어야합니다.

HTTP 레벨에서 커밋/롤백 트랜잭션을 의미 론적으로 시행 할 수는 없습니다. 트랜잭션 자체를 ReST 리소스로 모델링하지 않으면 훨씬 복잡한 일입니다.

그러나, 패치의 일부 속성은이 사용할 수 있도록 :

  • 은 HTTP에 패치가 원자해야하며 여러 자원에서 작동 할 수 있습니다.RFC 5789는 :
    • 서버는 원자 적 변화의 전체 세트를 제공 적용해서는 안 (예를 들면,이 작업시에 GET 응답하여) 부분적으로 변형 된 표현. 전체 패치 문서를 성공적으로 적용 할 수없는 경우 서버는 변경 사항을 적용해서는 안됩니다.
    • PATCH 방법은 Request-URI로 식별되는 자원에 영향을 미치며 다른 자원에도 부작용이있을 수 있습니다. 즉, PATCH의 애플리케이션에 의해 새로운 자원이 생성되거나 기존 자원이 수정 될 수있다. PATCH 안전도
  • JSON 패치 여러 자원에 여러 작업으로 구성 될 수 있습니다 나무 등도 모두 적용해야하거나 아무것도 그것을 암시 적 트랜잭션을 만들고, 적용되어야합니다. RFC 6902 :
    작업은 배열에 나타나는 순서대로 순차적으로 적용됩니다.

따라서 수정본은 개별 리소스로 모델링 될 수 있으며 동시에 업데이트 될 수 있습니다. 현재 개정판을 조회하는 것은 간단한 방법입니다. 트랜잭션을 커밋하는 것은 먼저 개정판의 테스트를 포함하는 단일 PATCH 요청이며, 그런 다음 자원에 대한 작업과 마지막으로 개정 자원을 업데이트하는 작업입니다.

서버는 여전히 수정본을 주 리소스의 ETag로 게시 할 수 있습니다.