2012-05-09 16 views
8

OK, tôi đã biết tất cả những lý do trên giấy tại sao tôi nên không sử dụng một HTTP GET khi thực hiện cuộc gọi RESTful để cập nhật trạng thái của một cái gì đó trên máy chủ. Vì vậy, có thể trả về dữ liệu khác nhau mỗi lần. Và tôi biết điều này là sai cho sau này 'trên giấy' lý do:Tại sao sử dụng HTTP GET để cập nhật trạng thái trên máy chủ trong một cuộc gọi RESTful không chính xác?

  • HTTP GET cuộc gọi nên được idempotent
  • N> 0 cuộc gọi nên luôn luôn GET cùng một dữ liệu trở lại
  • Vi phạm HTTP đặc tả
  • Cuộc gọi HTTP GET thường chỉ đọc

Và tôi chắc chắn có nhiều lý do hơn. Nhưng tôi cần một ví dụ đơn giản cụ thể để biện minh khác hơn là "Vâng, điều đó vi phạm HTTP Spec!". ... hoặc ít nhất tôi đang hy vọng một. Tôi có cũng đã đọc những điều sau đây mà có nhiều dọc theo dòng của danh sách trên: Does it violate the RESTful when I write stuff to the server on a GET call? & HTTP POST with URL query parameters -- good idea or not?

Ví dụ, ai đó có thể biện minh cho việc nêu trên và tại sao nó là sai/thực hành xấu/không chính xác để sử dụng một HTTP GET nói với các cuộc gọi RESTful sau đây

"MyRESTService/GetCurrentRecords?UpdateRecordID=5&AddToTotalAmount=10" 

Tôi biết điều đó sai, nhưng hy vọng nó sẽ giúp cung cấp một ví dụ để trả lời câu hỏi ban đầu của tôi. Vì vậy, ở trên sẽ cập nhật recordID = 5 với AddToTotalAmount = 10 và sau đó trả về các bản ghi được cập nhật. Tôi biết một POST nên được sử dụng, nhưng giả sử tôi đã sử dụng GET.

Cách chính xác và trả lời câu hỏi của tôi hoặc điều này có gây ra sự cố thực tế không? Ngoài tất cả các vi phạm từ danh sách dấu đầu dòng ở trên, làm cách nào để sử dụng HTTP GET để thực hiện việc trên gây ra một số vấn đề thực sự? Quá nhiều lần tôi đi vào một kịch bản mà tôi có thể biện minh cho mọi việc bằng "Bởi vì tài liệu đã nói như vậy", nhưng tôi cần biện minh và hiểu rõ hơn về điều này.

Cảm ơn!

+2

Nó không gây ra vấn đề thực sự nếu bạn đồng ý với việc truy vấn cập nhật của bạn có thể được kích hoạt lại bất kỳ lúc nào (truy vấn bộ nhớ cache, bot, v.v.). Kết luận của tôi là nếu một người trong nhóm của tôi, biết vấn đề bởi vì anh ấy đã đọc các câu hỏi SO mà bạn đã liên kết, sử dụng GET cho một truy vấn cập nhật, thì tôi nên xem xét một biện pháp kỷ luật. –

+2

bạn sẽ nói gì nếu ai đó đã viết phương thức có tên GetSomething (id, giá trị) trong một số API của bên thứ ba và bạn phải sử dụng nó? –

+1

Đó là một chút giống như hỏi tại sao một chức năng gọi là "GetSomeResource" không thể trong thực tế đặt tài nguyên. Về mặt kỹ thuật, bạn có thể làm điều đó nhưng sau đó may mắn duy trì API và chúc may mắn cho bất kỳ ai phải sử dụng nó. –

Trả lời

15

Trường hợp thực tế mà bạn sẽ gặp sự cố là HTTP GET thường được thử lại trong trường hợp không thực hiện được HTTP. Vì vậy, bạn có thể trong cuộc sống thực nhận được các tình huống mà cùng một GET được nhận nhiều lần bởi máy chủ. Nếu bản cập nhật của bạn là idempotent (là của bạn), thì sẽ không có vấn đề gì, nhưng nếu nó không phải là idempotent (như thêm một số giá trị vào một số tiền chẳng hạn), thì bạn có thể nhận được nhiều cập nhật (không mong muốn).

HTTP POST không bao giờ được thử lại, vì vậy bạn sẽ không bao giờ gặp phải vấn đề này.

+0

Có chính xác - Tôi đang cố gắng thực hiện cuộc gọi * không * không đáng tin cậy và tôi đoán tôi vẫn còn một cuộc gọi. Tôi vừa cập nhật ví dụ của mình với 'AddToTotalAmount = 10' để làm cho cuộc gọi không phải là không cần thiết. – atconway

+0

Việc thử lại GET có phải là lỗ hổng chính duy nhất mà bạn có thể thấy không? Một trong những tuyệt vời mặc dù và vẫn biện minh đủ, chỉ cần tự hỏi nếu có thêm lý do. – atconway

+1

Vâng, đó thực sự là người duy nhất xa như tôi biết. Nếu bạn nhìn vào các triển khai HTTP thực sự là sự khác biệt duy nhất giữa GET và các yêu cầu HTTP khác. –

-2

tôi nghĩ rằng việc đọc tài nguyên này: http://www.servicedesignpatterns.com/WebServiceAPIStyles có thể hữu ích cho bạn để tạo sự khác biệt giữa API thông báo và tài nguyên api?

+0

Xin lỗi, liên kết này không giúp ích gì cho câu trả lời cho câu hỏi cụ thể mà tôi đang hỏi về việc sử dụng HTTP GET trong các tình huống khi sử dụng HTTP POST. – atconway

+0

trong câu hỏi của bạn, bạn cung cấp url không phải là một phần của REST API và nó có semnatic RPC điển hình, nơi bạn đặt tên phương thức trong url: addTotalAmount –

+0

Đó là một giả tạo được tạo thành ví dụ về cuộc gọi REST không đúng để giúp trích xuất câu trả lời cho câu hỏi của tôi . – atconway

3

Nếu một số loại công cụ tìm kiếm thu thập dữ liệu trang web của bạn, nó có thể thay đổi dữ liệu của bạn một cách vô tình.

Điều này đã xảy ra trong quá khứ với Tìm kiếm trên máy tính để bàn của Google khiến mọi người mất dữ liệu vì mọi người đã triển khai hoạt động xóa dưới dạng GET.

+1

haha, đó là một câu chuyện khá thú vị! –

1

Đây là lý do quan trọng mà GET phải là không đáng kể và không được sử dụng để cập nhật trạng thái trên máy chủ liên quan đến các cuộc tấn công yêu cầu Cross Site Request. Từ cuốn sách: Professional ASP.NET MVC 3

idempotent GET
Big văn bản, chắc chắn - nhưng đó là một khái niệm đơn giản. Nếu hoạt động là không có giá trị, nó có thể được thực hiện nhiều lần mà không cần thay đổi kết quả bằng cách . Nói chung, nguyên tắc chung là bạn có thể ngăn chặn toàn bộ lớp tấn công CSRF bằng cách chỉ thay đổi mọi thứ trong số DB hoặc trên trang web của bạn bằng cách sử dụng POST. Điều này có nghĩa là Đăng ký, Đăng xuất, Đăng nhập, v.v. Ít nhất, điều này hạn chế một chút các cuộc tấn công phó bối rối.

Các vấn đề liên quan