Một số điều cần lưu ý khi thao tác với RESTful Web Service (P1)
Khi phát triển một RESTful Web Service, việc phải chọn lựa giữa hai phương thúc HTTP PUT hay POST cho việc tạo hoặc sửa một tài nguyên là một trong những điều dễ gây bối rối cho các lập trình viên Web nhất. Do cả hai phương thức đều có thể được dùng để submit dữ liệu, bạn có thể dùng cả POST và PUT ...
Khi phát triển một RESTful Web Service, việc phải chọn lựa giữa hai phương thúc HTTP PUT hay POST cho việc tạo hoặc sửa một tài nguyên là một trong những điều dễ gây bối rối cho các lập trình viên Web nhất. Do cả hai phương thức đều có thể được dùng để submit dữ liệu, bạn có thể dùng cả POST và PUT cho việc tạo và sửa một tài nguyên. Nhiều lập trình viên Web muốn sử dụng PUT cho việc tạo tài nguyên vì nó bảo đảm vẹn toàn cho dữ liệu. Cho dù bạn có gọi phương thức PUT bao lần đi nữa, trạng thái của tài nguyên cũng đều không bị ảnh hưởng. Nhất là trong các trường hợp mạng bị chậm, khả năng xảy ra hiện tượng submit nhiều lần một dữ liệu là rất cao, sử dụng PUT sẽ giúp cho việc này trở nên dễ dàng hơn, vì bạn không cần phải quan tâm đến việc người dùng click nút submit nhiều lần nữa. Nhưng, mấu chốt cần phải nhớ là khi bạn dùng PUT để tạo một resource bạn cần phải cung cấp id cho nó. Ví dụ:
PUT /book/{id}
Vì phần lớn các hệ thống muốn giữ việc kiểm soát đối với id , ví dụ họ muốn tự sinh ra id theo ý của họ trong cơ sở dữ liệu, hơn là việc để client chỉ định id, thì PUT có lẽ không phải là một phương thức phù hợp để có thể tạo resource. Sử dụng phương thức này cũng phải đối mặt với việc nhiều người dùng sẽ gửi request PUT để tạo tài nguyên với cùng một id và thay vì tài nguyên mới được tạo thì nó sẽ được cập dữ liệu mới.
Cho dù phương thức POST không đảm bảo tính vẹn toàn dữ liệu, nó vẫn là lựa chọn tốt hơn cho việc tạo một tài nguyên vì nó không yêu cầu người dùng cung cấp một id cho tài nguyên đó. Thay vào đó, khi phương thức POST hoàn thành nó sẽ trả về id và URI của tài nguyên vừa mới được tạo trên Header của response. Điều này cho phép người dùng có thể tiếp tục update tài nguyên vừa được tạo. Bạn có thể tìm xem quyển HTTP: The Definitive Guide được viết bởi David Gourley để có thể hiểu thêm về tính toàn vẹn dữ liệu và các phương thức an toàn của giao thức HTTP. Đây cũng là một trong các quyển sách nên đọc nhất dành cho các lập trình viên Web.
Và cũng tương tự như vậy, PUT là sự lựa chọn tốt hơn cho việc cập nhật tài nguyên vì bạn đã có sẵn id của tài nguyên đó và nó không đổi, cho nên ngay cả khi người dùng submit nhiều request PUT một lúc thì trạng thái của tài nguyên cũng sẽ không bị ảnh hưởng. Đó là tất cả về việc phân biệt trường hợp sử dụng của PUT và POST, câu trả lời ngắn gọn là, POST được dùng để tạo một tài nguyên và PUT được sử dụng để update tài nguyên, tuy đây không phải điều bắt buộc nhưng sử dụng như vậy sẽ logic hơn trừ khi bạn có thể tiên lượng được tất cả các vấn đề khi phát triển ứng dụng.
Để có thể làm việc hiệu quả với REST và RESTful web service, bạn cần có kiến thức tốt về HTTP. Dù rằng làm việc với REST có thể không quá là khó khăn, nhưng việc thiết kế một RESTful API đồng bộ và đồng nhất là mộ việc không hề dễ dàng. Một trong các nhiệm vụ khó khăn đó là việc phải chọn lựa phương thức HTTP phù hợp với công việc tương ứng ví dụ như việc lựa chọn khi nào dùng POST khi nào dùng POST ở trên. Một khi bạn hiểu được ý nghĩa và mục đích sử dujgn của các phương thwusc HTTP khác nhau, bạn sẽ có thể dễ dàng chọn lựa phương thức phù hợp. Bạn có thể phân loại các phương thức HTTP ra thành hai mục chính An Toàn và Bảo Toàn Dữ Liệu. Các phương thức HTTP An toàn là các phương thức không thay đổi tài nguyên ví dụ phương thức GET là một phương thức an toàn vì nó không làm thay đổi tài nguyên mà bạn đang request. Một phương thức HTTP an toàn khác đó là HEAD, nó không làm thay đổi trạng thái biểu diễn của tài nguyên trên Server, còn lại tất cả các phương thức HTTP khác như POST, PUT hay DELETE được coi là không an toàn.
Tiếp theo là phương thức Bảo toàn dữ liệu, đó là các phương thức HTTP có thể được gọi nhiều lần và kết quả được sinh ra sau mỗi lần là giống nhau. Những phương thức đó được coi là lựa chọn an toàn để cập nhật một tài nguyên trên Server. Một vài ví dụ của các phương thức HTTP bảo toàn dữ liệu là GET, PUT và PATCH. Cho dù bạn có gọi các phương thức này bao nhiêu lần thì nó cũng sẽ trả về cùng một URI. Hãy cùng đi thêm chi tiết hơn vào hai mục phân loại này.
Thế nào là các phương thức an toàn trong HTTP
Đây là các phương thức HTTP không tạo sự thay đổi với tài nguyên trên phía server. Ví dụ, gửi một GET hay HEAD request lên URL của một tài nguyên KHÔNG nên làm thay đổi tài nguyên đó. Các phương thức an toàn này có thể được Cache hoặc Prefetched (tải trước) mà không để lại hậu quả hay tác dụng phụ gì cho tài nguyên. Sau đây là một ví dụ về phương pháp an toàn.
GET /order/123 HTTP/1.1
Phương thức trên sẽ lấy về đơn hàng với orderID là 123. Cho dù bạn có thực hiện request trên bao nhiêu lần đi nữa, thì đơn hàng ở trên server cũng sẽ không bị thay đổi hay ảnh hưởng. Đó là lý do vì sao phương thức GET là một phương thức an toàn.
Thế nào là các phương thức bảo toàn dữ liệu trong HTTP
Đây là các phương thức bảo đảm sự an toàn khi bị gọi nhiều lần một lúc. Phương thức này sẽ chỉ thay đổi tài nguyên trên Server mỗi khi bạn gọi nó nhưng kết quả trả về cuối cùng vẫn sẽ giữ nguyên. Hãy xem ví dụ sau:
int i = 30; // bảo toàn dữ liệu i++; // không bảo toàn dữ liệu
Ở đây toán tử gán là phương thức bảo toàn ữ liệu, cho dù bạn thực hiện mệnh đề này bao nhiêu lần thì i vẫn bằng 4. Ở dòng thứ hai dữ liệu không được bảo toàn, việc bạn thực thi mệnh đề đó 10 lần kết quả sẽ khác với việc thực thi nó 5 lần. Tính bảo toàn dữ liệu là một vấn đề quan trọng khi xây dựng một RESTful API. Tính bảo toàn dữ liệu cũng là lý do vì sao bạn cần biết khi nào dùng POST và khi nào dùng PUT để cập nhật một tài nguyên trong REST. Nếu một người dùng muốn update một tài nguyên bằng phương thức POST, việc gọi phương thức này quá nheieuf lần có thể sẽ tạo ra các kết quả update khác nhau.
Trong thực tế, trường hợp khi ta gửi một POST request và bị timeout, ta sẽ phải phân vân liệu rằng tài nguyên đó đã thực sự được cập nhật chưa? Liệu sự cố timeout này xảy ra trong lúc ta đang gửi request lên server hay response đang được trả về cho client? Liệu ta có thể thực hiện Retry request một cách an toàn hay ta cần trước tiên phải xem điều gì đã xảy ra với tài nguyên? Nếu sử dụng phương thức PUT, bạn có thể sẽ không bao giờ phải phân vân những điều trên, mà còn có thể gửi lại request một cách an toàn cho tới khi ta thực sự nhận được kết quả trả về từ server.
Sau đây là tổng kết của việc phân loại phương thức HTTP nào an toàn, phương thức nào bảo toàn dữ liệu:
- GET là phương thức An Toàn và Bảo toàn dữ liệu.
- HEAD là phương thức An Toàn và Bảo toàn dữ liệu.
- OPTIONS phương thức An Toàn và Bảo toàn dữ liệu.
- PUT là phương thức bảo toàn dữ liệu nhưng không an toàn.
- DELETE là phương thức bảo toàn dữ liệu nhưng không an toàn.
- POST là phương thức không an toàn và không bảo đảm dữ liệu.
- PATCH là phương thức không an toàn và không bảo đảm dữ liệu.
Hãy nhớ rằng, phương thức an toàn là phương thức không làm thay đổi biểu diễn của tài nguyên trên Server ví dụ như GET không làm đổi nộ dung trang web bạn truy cập, đây là các phương thức chỉ đọc. Còn các phương thức bảo toàn dữ liệu sẽ không trả về kết quả khác nhau sau khi gjoi nhiều lần trừ khi bạn đổi URL.