2011-11-15 44 views
26

Tôi muốn thực hiện các cập nhật một phần cho tài nguyên của mình vì tôi có tài nguyên lớn và muốn cập nhật thông tin một phần từ nó.Tôi đã đi qua các liên kết sau đây chứ không phải
để tìm hiểu xem có sử dụng các phương thức HTTP POST hoặc PATCH hay không.Làm thế nào để hỗ trợ một phần Cập nhật (PATCH) trong REST

HTTP MODIFY verb for REST?

How to submit RESTful partial updates?

http://jacobian.org/writing/rest-worst-practices/

https://github.com/archiloque/rest-client/issues/79

http://tools.ietf.org/html/draft-dusseault-http-patch-16

http://greenbytes.de/tech/webdav/draft-dusseault-http-patch-06.html

http://jasonsirota.com/rest-partial-updates-use-post-put-or-patch

http://bitworking.org/news/296/How-To-Do-RESTful-Partial-Updates

https://github.com/dharmafly/jsonpatch.js

Xin gợi ý cho bất kỳ giải pháp hợp lệ cho việc này.

+0

@prashanath u có bất kỳ giải pháp – CoronaPintu

Trả lời

90

Theo RFC5789 (http://tools.ietf.org/html/rfc5789), đây chính xác là những gì PATCH dành cho:

Một vài ứng dụng mở rộng Hypertext Transfer Protocol (HTTP) yêu cầu một tính năng để thực hiện sửa đổi một phần tài nguyên. Phương thức HTTP PUT hiện tại chỉ cho phép thay thế hoàn toàn tài liệu. Đề xuất này thêm phương thức HTTP mới, PATCH, để sửa đổi tài nguyên HTTP hiện tại .

Sự khác biệt giữa PATCH và PUT được mô tả như sau:

Sự khác biệt giữa các yêu cầu PUT và PATCH được phản ánh trong cách máy chủ xử lý thực thể kèm theo để thay đổi tài nguyên xác định bởi các Yêu cầu-URI. Trong một yêu cầu PUT, thực thể đính kèm được coi là phiên bản được sửa đổi của tài nguyên được lưu trữ trên máy chủ gốc và khách hàng yêu cầu phiên bản đã lưu được thay thế. Tuy nhiên, với PATCH, thực thể kèm theo chứa một tập hợp hướng dẫn mô tả cách tài nguyên hiện đang cư trú trên máy chủ gốc cần được sửa đổi để tạo phiên bản mới.

Những hạn chế của POST cũng được mô tả:

Phương pháp PUT đã được xác định để ghi đè lên một nguồn tài nguyên với một cơ thể mới hoàn thành, và không thể được tái sử dụng để làm thay đổi một phần. Nếu không, proxy và bộ nhớ cache, và thậm chí cả khách hàng và máy chủ, có thể nhận được nhầm lẫn với kết quả của hoạt động. POST đã được sử dụng nhưng không khả năng tương tác rộng (cho một, không có cách nào tiêu chuẩn để khám phá hỗ trợ định dạng bản vá) [...]

tôi sẽ đề nghị bạn đọc RFC và làm cho tâm trí của riêng bạn, nhưng với tôi điều này có vẻ khá rõ ràng - yêu cầu PATCH nên được xử lý như là một phần cập nhật. (NB họ KHÔNG idempotent, không giống như PUT.)

EDIT: như đã chỉ ra bởi Eugene trong các ý kiến, mặc dù yêu cầu PATCH được "neither safe nor idempotent as defined by [RFC2616]", họ có thể được thực hiện như vậy:

Yêu cầu PATCH có thể được ban hành theo cách như vậy để trở thành idempotent, cũng giúp ngăn chặn các kết quả xấu từ các va chạm giữa hai yêu cầu PATCH trên trên cùng một tài nguyên trong một khung thời gian tương tự. Va chạm từ nhiều yêu cầu PATCH có thể nguy hiểm hơn Va chạm PUT vì một số định dạng bản vá cần phải hoạt động từ điểm cơ sở đã biết hoặc nếu không chúng sẽ làm hỏng tài nguyên. Khách hàng sử dụng loại ứng dụng bản vá này NÊN sử dụng yêu cầu có điều kiện sao cho yêu cầu sẽ thất bại nếu tài nguyên đã được cập nhật kể từ khi khách hàng truy cập tài nguyên lần cuối. Ví dụ: khách hàng có thể sử dụng ETF mạnh [RFC2616] trong tiêu đề If-Match trên yêu cầu PATCH .

+20

+1 Tôi có thể thêm rằng 'PATCH' có thể được thực hiện ** idempotent ** bằng cách bao gồm' If-Match 'header, như được mô tả trong RFC mà bạn đang đề cập đến. Nó thực sự là đề nghị mạnh mẽ trong RFC để làm điều đó, khi áp dụng các bản vá lỗi cho phiên bản sai có thể làm hỏng một tham chiếu, trái ngược với một PUT mà chỉ thay thế toàn bộ điều. –

+0

True - mặc dù để có được điều này tất cả làm việc bạn cũng sẽ cần phải được tạo ra/sử dụng ETags một cách chính xác. –

+0

Dù sao thì cũng là một ý tưởng hay, hãy nói cho bộ nhớ đệm, nhưng đặc biệt để thực hiện các cập nhật từng phần, nơi bạn thường muốn đảm bảo rằng bạn đang vá một phiên bản tài nguyên cụ thể. Đôi khi, đủ thông tin ngữ cảnh có thể được nhúng vào khác, nhưng ETags là một cách độc lập với định dạng khác thường dễ dàng tích hợp vào các khung công tác chung không biết gì về các định dạng khác biệt cụ thể. –

-17

PATCH sẽ được sử dụng với định dạng bản vá, chỉ dành cho bản vá cấp tài liệu (còn gọi là khác biệt về cách trình bày thực tế). Việc sử dụng nó cho các mục đích khác là đáng ngờ và gây tranh cãi, và nó không rõ ràng rằng phương pháp này được thiết kế để sử dụng không phải là phương tiện truyền thông.

Nói chung, POST sẽ là phương pháp phù hợp, nhưng bạn có thể muốn chia tài nguyên của mình thành nhiều tài nguyên thay vào đó và thay đổi các tài nguyên đó thay thế.

[Sửa cho rõ ràng, như một số không đọc comments]

+6

tôi không xem các yêu cầu * prashanth *: 'cập nhật từng phần cho tài nguyên của tôi 'sẽ xung đột với những gì PATCH được cho là: thực thể chứa một tập hợp các hướng dẫn mô tả cách một tài nguyên hiện đang cư trú trên máy chủ gốc sẽ được sửa đổi để tạo ra một phiên bản mới .' Đây là từ ** rfc5789 **, nhưng cũ hơn ** rfc2068 ** là tương tự. Cũng liên quan đến 'diff trên byte thực tế', bạn có thể không bị nhầm lẫn với các phạm vi HTTP mà chỉ cần các trình triển khai thực hiện các phạm vi byte (nhưng điều này có thể được mở rộng sang các đơn vị khác)? –

+1

Tôi không nhầm lẫn các yêu cầu phạm vi http với tài liệu bản vá, không, cảm ơn bạn đã chỉ ra sự nhầm lẫn có thể xảy ra với người đọc. Đặc tả trong câu hỏi khá rõ ràng về tài liệu bản vá là tài liệu sửa đổi trạng thái của tài nguyên, ít rõ ràng hơn về cách áp dụng tài liệu đó, để lại sự lựa chọn cho bạn. Từ một quan điểm cụ thể, nó được khuyến khích để làm điều kiện, và etags mạnh mẽ được đưa ra trong ví dụ, mà chúng ta biết là đại diện cụ thể. Các định dạng khác nhau đã biết hoặc được xuất bản (mà bạn sử dụng trong ReST) là tài liệu cụ thể, do đó, câu trả lời của tôi. – SerialSeb

+3

Nói chung, yêu cầu POST được sử dụng để tạo tài nguyên, không cập nhật chúng. – ChrisV

0

Bạn nên sử dụng phương pháp PATCH như được mô tả trong RFC-7386 "json merge PATCH".

Ví dụ: nếu bạn muốn thay đổi giá trị của "a" và loại bỏ "e" trong tài nguyên như:

{ 
    "a": "b", 
    "c": { 
     "d": "e", 
     "f": "g" 
    } 
    } 

Bạn có thể đạt được điều này bằng cách gửi:

 PATCH /target HTTP/1.1 
     Host: example.org 
     Content-Type: application/merge-patch+json 

     { 
     "a":"z", 
     "c": { 
      "f": null 
     } 
     } 
Các vấn đề liên quan