Skip to content

Instantly share code, notes, and snippets.

@khanhhd
Last active December 25, 2015 00:19
Show Gist options
  • Save khanhhd/6887022 to your computer and use it in GitHub Desktop.
Save khanhhd/6887022 to your computer and use it in GitHub Desktop.

##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_atupdated_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 partialside-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/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment