##Edge Rails: PATCH là phương thức chính mới của HTTP cho việc cập nhật.
##PATCH là gì?
PUT
method trong HTTP là việc tạo ra hay thay thế một resource
tại một URL
nào đó.
Trong ví dụ này giả sử bạn có nhiều file, nếu bạn upload 1 file vào S3 ở một URL
nào đó, bạn muốn hoặc là tạo ra một file tại URL
đó hoặc là thay thế một file đã tồn tại. Đó là PUT
.
Bây giờ hãy giả sử rằng có một ứng dụng web có một model Invoice
với paid
một cờ trạng thái chỉ ra rằng khi nào thì hóa đơn (invoice
) đã được thanh toán (paid
là một trường trong db). Làm thế nào để có thể gán (cập nhật) cờ paid
theo cách RESTful
? Submit paid=1
thông qua phương thức PUT
/invoices/:id
không phù hợp với HTTP về mặt ngữ nghĩa bởi vì request không gửi một complete representation
của invoice
cho việc thay thế resource
.
Nhưng giới hạn của các phương thức GET
, POST
, PUT
, DELETE
. Câu trả lời truyền thống là định nghĩa paid
flag thành một resource
riêng, và là một phần của invoice
. Bạn định nghĩa một rout để có thể PUT paid=1 tới /invoices/:id/paid. Bạn làm được điều này bởi vì PUT
không cho phép cập nhật từng phần vào resource
.
Bây giờ hãy nghĩ về một form edit
thường dùng trong ứng dụng Ruby On Rails. Bao nhiêu lần chúng ta gửi một complete representation
cho việc thay thế? Không thường xuyên, có lẽ chúng ta thậm chí có thể nói rằng việc đó hiếm trong thực tiễn. Ví dụ quy ước created_at
và updated_at
timestamps
thông thường không thể được gán bởi người dùng cuối. Thông qua đó, chúng thường được coi là thuộc về representation của resource
( representation
có thể hiểu là biểu diễn dữ liệu của resource
ví dụ như json, csv, html...) mà nó sẽ được ánh xạ vào bản ghi trong cơ sở dữ liệu.
Thêm vào đó PUT là một phương thức idempotent
. Bạn có thể gửi lại request nhiều lần như bạn muốn và lấy về cùng một resource
, có một vài thứ đôi khi bị vi phạm các ngữ nghĩa thông thường cho việc tạo một resource
con sử dụng nested attribuets
trong khi cập nhật resource
cha. Về mặt lý thuyết không có gì có thể ngăn chặn PUT
update partial, nhưng khi HTTP đã được tiêu chuẩn hóa việc thay thế resource
đã được triển khai.
Chính vì lý do đó, PATCH method ra đời năm 1995 và đã được tiêu chuẩn hóa sau đó. PATCH là một method không an toàn, hay không idempotent
, và cho phép update full
hoặc partial
và side-effects
trên các resource
khác.
Trong thực tế bạn cũng có thể thấy, PATCH ngày càng phù hợp với chương trình web và cách thức tốt hơn so với PUT
cho việc update resource
. Trong Ruby on Rails PATCH được dùng trong update_attributes
cho việc update record.
Do đó, PATCH trở thành một phương thức quan trọng trong Ruby on Rails 4.0.
##Routing
Đây là một sự thay đổi quan trọng nhưng chúng ta có kế hoạch để nó tương thích ngược trở lại.
Khi một resource
được khai báo trong config/routes.rb
ví dụ
resources :users
Action trong UsersController
vẫn là update
( rails 4)
Gửi một PUT
request tới /uers/:id
trong Rails 4 routes sẽ trỏ tới update.
Trong rails 4.0 routes cũng gọi PATCH method khi request /users/:id
tới action update
Vậy trong rails 4 hỗ trợ cả PATCH và PUT
cho việc update
##Form
Form of persisted resources
form_for @user
Lấy một “patch” trong hidden_field “_method”.
<input type="hidden" value="patch" name="_method"></input>
RFC
cố ý làm mập mờ về cách thức mô tả cho những thay đổi trong PATCH request. Submit một form hợp lệ, client và server chỉ đơn giản là phải đồng ý cách thức để update resource
.
Tôi xin nhấn mạnh rằng hack "_method" là một cách giải quyết cho những giới hạn trong các trình duyệt web. Như bạn có thể biết các định thực sự trong các phương thức của HTTP . Đó là, PUT
, DELETE
, và bây giờ, PATCH request được chuyển đến action tương ứng.
##General availability
PATCH request có thể sử dụng được ở mọi nơi mà các method còn lại có thể sử dụng được. Có một macro
cho các routes DSL
,:via
hiểu được symbol :path. Test có thể đưa ra PATCH request, các đối tượng yêu cầu phản hồi lại PATCH?, Vv Xin vui lòng xem các commit ban đầu để biết chi tiết (với một followup quan trọng ở đây).
##Web server của tôi sẽ hiểu PATCH?
Vâng nó có thể, tôi đã cố gắng thử Apache, nginx, Phusion Passenger, Unicorn, Thin, and WEBrick, chúng đều hiểu được PATCH request.
Ngoài ra HTTP client nói chung có thể đưa ra một PATCH request. ví dụ:
curl -d'user[name]=wadus' -X PATCH http://localhost:3000/users/1
##REFERENCE http://weblog.rubyonrails.org/2012/2/25/edge-rails-patch-is-the-new-primary-http-method-for-updates/