2013-05-03 83 views
12

Tôi đang thiết kế một API và tôi tự hỏi liệu có nên gửi một tải trọng JSON lên một yêu cầu GET không?Tải trọng yêu cầu HTTP

Trong câu hỏi này khác Payloads of HTTP Request Methods, chúng ta có thể tìm theo this link:

  • HEAD - ngữ nghĩa cơ thể Không xác định.
  • NHẬN - Không xác định ngữ nghĩa cơ thể.
  • PUT - Thân máy được hỗ trợ.
  • BÀI ĐĂNG - Thân máy được hỗ trợ.
  • XÓA - Không xác định ngữ nghĩa cơ thể.
  • TRACE - Nội dung không được hỗ trợ.
  • TÙY CHỌN - Nội dung được hỗ trợ nhưng không có ngữ nghĩa (có thể trong tương lai).

Điều này có nghĩa là tôi không nên gửi yêu cầu GET có tải trọng không? Có rủi ro không?

  • Giống như việc một số thư viện máy khách HTTP không thể gửi tải trọng như vậy?
  • Hoặc mã Java API của tôi không được di chuyển trên một số máy chủ ứng dụng nhất định?
  • Còn gì nữa không?

tôi phát hiện ra rằng ElasticSearch đã sử dụng một tải trọng như vậy trên một yêu cầu GET:

$ curl -XGET 'http://localhost:9200/twitter/tweet/_search?routing=kimchy' -d '{ 
    "query": { 
     "filtered" : { 
      "query" : { 
       "query_string" : { 
        "query" : "some query string here" 
       } 
      }, 
      "filter" : { 
       "term" : { "user" : "kimchy" } 
      } 
     } 
    } 
} 
' 

Vì vậy, nếu THƯ VIỆN phổ biến này làm nó và không ai phàn nàn, thì có lẽ tôi có thể làm như vậy?

Nhân tiện, Tôi muốn biết liệu điều này có được phép trộn các tham số queryString và tải trọng JSON không? Chính xác như truy vấn ElasticSearch này. Nếu có, có quy tắc nào để chúng ta biết đối số nào là tham số queryString hay thông số tải trọng?


Ở đây chúng ta có thể đọc: Cảm nhận HTTP GET with request body

Roy Fielding về bao gồm một cơ thể với một yêu cầu GET.

Có. Nói cách khác, bất kỳ thông báo yêu cầu HTTP nào cũng được phép chứa nội dung thư và do đó phải phân tích cú pháp thư với ý nghĩ đó. Tuy nhiên, máy chủ ngữ nghĩa cho GET bị hạn chế sao cho nội dung, nếu có, không có ý nghĩa ngữ nghĩa đối với yêu cầu. Các yêu cầu về phân tích cú pháp riêng biệt với các yêu cầu về ngữ nghĩa của phương pháp.

Vì vậy, có, bạn có thể gửi nội dung bằng GET, và không, nó không bao giờ hữu ích để làm như vậy.

Đây là một phần của thiết kế lớp của HTTP/1.1 sẽ trở nên rõ ràng một lần nữa khi thông số được phân đoạn (công việc đang tiến hành).

.... Roy

Sau đó, tôi thực sự không hiểu tại sao nó không bao giờ là hữu ích, vì nó có ý nghĩa trong quan điểm của tôi để gửi truy vấn phức tạp đến máy chủ đó sẽ không phù hợp tốt trên queryParam hoặc matrixParam. Tôi nghĩ rằng các nhà thiết kế ElasticSearch API nghĩ giống nhau ...


Tôi đang lên kế hoạch để thiết kế một API mà có thể được gọi như thế:

curl -XGET 'http://localhost:9000/documents/inbox?pageIndex=0&pageSize=10&sort=title' 

curl -XGET 'http://localhost:9000/documents/trash?pageIndex=0&pageSize=10&sort=title' 

curl -XGET 'http://localhost:9000/documents/search?pageIndex=0&pageSize=10&sort=title' -d '{ 
    "someSearchFilter1":"filterValue1", 
    "someSearchFilter2":"filterValue2", 
    "someSearchFilterList": ["filterValue3","xxx"] 
    ... a lot more ... 
} 
' 

Liệu nó có vẻ tốt đẹp đối với bạn? Dựa trên những cân nhắc ở trên.


+1

một rủi ro sẽ là thư viện khách hàng sẽ không cho phép tải trọng được gửi trong một GE T yêu cầu. Tôi thậm chí không nhận ra bạn có thể làm điều này với curl, trung thực. – bdkosher

Trả lời

1

Có phản hồi GET khác nhau tùy theo yêu cầu sẽ phá vỡ bộ đệm ẩn. Đừng đi đến đó.

+0

Đây là một API mà tôi không cần bộ nhớ đệm vì nó được contextualized bởi một tiêu đề OAuth2 xác định khách hàng. Các máy khách khác nhau có thể có các biểu diễn khác nhau của cùng một tài nguyên URI, do đó tôi không thể thực hiện bộ nhớ đệm dựa trên tài nguyên URI –

+0

Tất cả các thư viện trung gian/thư viện có nhận thức được điều đó không? –

+0

chắc chắn vì họ cần truy cập mã thông báo OAuth2 cho phép họ thao tác tài khoản người dùng. Do đó tài nguyên/profile là hồ sơ người dùng mà khách hàng có mã thông báo OAuth2 (được cung cấp dưới dạng Tiêu đề) –

1

Google App Engine, một khung công tác web phổ biến, sử dụng thư viện tìm nạp url đặc biệt, trong đó does not support making HTTP GET requests with a payload. Theo đó, nếu bạn muốn API của mình tiếp cận người dùng Google App Engine, thì tôi sẽ không khuyên bạn nên yêu cầu hành vi này.

Tôi đã mở an issue regarding this với google.

+0

Lưu ý rằng nếu bạn cần thực hiện yêu cầu 'GET', bạn có thể mã hóa phần thân của yêu cầu trong tham số chuỗi truy vấn' nguồn' thay vì gửi nó với phần thân của yêu cầu. –

0

Chỉ vì bạn có thể làm điều gì đó, không có nghĩa là bạn nên. Tôi xin lỗi nếu điều này nghe có vẻ bực mình nhưng điều về tiêu chuẩn là chúng là tiêu chuẩn - và HTTP là một trong những tiêu chuẩn được thiết lập nhất. Nó không hoàn hảo, và có rất nhiều thứ mà nhiều người muốn thay đổi, nhưng thực tế là gần như tất cả mọi người vẫn sử dụng các tham số URL cho các trường hợp sử dụng như thế này là để tôi chỉ ra rằng không có bất kỳ lựa chọn thay thế đáng tin cậy nào ngay bây giờ.

Câu trả lời từ speedplane và Julian Reschke đưa ra hai ví dụ cụ thể về những thứ sẽ bị hỏng nếu bạn dựa vào các yêu cầu GET với nội dung/tải trọng. Bạn có thể viết ứng dụng của bạn khác nhau cho mọi người khác, nếu bạn muốn, nhưng web là một lĩnh vực mà các tiêu chuẩn có lẽ nên được thực hiện nghiêm túc hơn bình thường. Tôi biết nó là hấp dẫn để trở thành một người đi đường, nhưng với tất cả sự tôn trọng, hãy xem xét có bao nhiêu trang web tồn tại, và có bao nhiêu lập trình viên web đang xây dựng và duy trì chúng. Nếu có cách nào tốt hơn, bạn có thể thấy nó được sử dụng rộng rãi trong sản xuất ngay bây giờ.

Thay đổi tiêu chuẩn/được chấp nhận chậm vì rất nhiều người phải đồng ý với họ để họ làm việc. Bạn đúng khi nói rằng có ứng dụng phá vỡ quy tắc, nhưng bạn sẽ nhận thấy chúng đã gây ra đau đầu cho mọi người và các biện pháp dự phòng/dự phòng là bắt buộc trong một số trường hợp nhất định, như đã đề cập trong Aetherus câu trả lời. Tôi có xu hướng đi theo con đường kháng cự ít nhất về các vấn đề như thế này. Nếu bạn thực sự muốn làm điều đó, tôi chắc chắn bạn có thể làm cho nó hoạt động, mặc dù.

1

Xem thêm: HTTP GET with request body - để biết thêm chi tiết về điều này.

Các ý chính là: Có bạn có thể, nhưng có lẽ bạn không nên vì những lý do khác nhau, bao gồm:

  • Bạn có thể bỏ qua các khuyến nghị HTTP spec (có thể bạn muốn POST)
  • Bạn có thể vấn đề giới thiệu bộ nhớ đệm
  • Đây là không trực quan như xa như các API REST đi
Các vấn đề liên quan