Bởi cuốn sách REST vs quá nhiều yêu cầu


8

Từ nhận xét của Roy Fielding về bài viết của chính mình đang giải mã apis REST giả :

Một API RESTful thực sự trông giống như siêu văn bản. Mỗi đơn vị thông tin có thể định địa chỉ mang một địa chỉ, rõ ràng (ví dụ: thuộc tính liên kết và id) hoặc ngầm định (ví dụ: xuất phát từ định nghĩa và cấu trúc biểu diễn loại phương tiện). Kết quả truy vấn được thể hiện bằng một danh sách các liên kết với thông tin tóm tắt, không phải bởi các mảng biểu diễn đối tượng (truy vấn không thay thế cho việc xác định tài nguyên).

Điều này có nghĩa là nếu bạn cần, giả sử, truy vấn danh sách 100 người dùng đã đăng nhập gần đây nhất và hiển thị tên và email của họ, trước tiên bạn cần thực hiện một GETtruy vấn cho danh sách kết quả, về cơ bản (về cơ bản) là một danh sách các thành phần liên kết, với mỗi đối tượng liên kết chứa URI của tài nguyên người dùng. Sau đó, bạn sẽ cần thực hiện thêm 100 GETyêu cầu - một yêu cầu cho mỗi tài nguyên người dùng - trước khi bạn thực sự có dữ liệu bạn cần để hiển thị kết quả của mình.

Điều đó có vẻ vô cùng kém hiệu quả. Có thực sự không có cách thực sự RESTful nào khác để có được dữ liệu bạn cần trong 1 hoặc 2 yêu cầu không?


1
Bạn đã không bỏ lỡ phần: "với thông tin tóm tắt"?
Luc Franken

1
Tôi đã không bỏ lỡ nó, nhưng "thông tin tóm tắt" ngụ ý "tóm tắt" với tôi, không phải "tất cả dữ liệu." Ông đặc biệt nói "không phải bằng các mảng biểu diễn đối tượng" - đó chính xác là những gì chúng ta cần cho màn hình của chúng tôi.
Giô-na

1
Chúng tôi xem danh sách này dưới dạng tài nguyên và đối với chúng tôi, nó chứa các trường như: liên kết đến tài nguyên đơn, tiêu đề, mô tả ngắn và # bình luận chẳng hạn. Chúng tôi không bao gồm các đối tượng đầy đủ vì chúng quá lớn. Vì vậy, tài nguyên danh sách của chúng tôi cung cấp đầy đủ tất cả thông tin cần thiết để sử dụng nó. Khi bạn muốn nhiều hơn, bạn tải toàn bộ tài nguyên có thể bao gồm các biểu mẫu, nhiều nội dung và các phần lớn hơn khác. Chúng tôi đã cố gắng một lần để bao gồm tất cả các tài nguyên (quá trình suy nghĩ của YAGNI) nhưng điều đó đã bị phá vỡ. Vì vậy, chúng tôi đã thêm bước này. Và tôi nghĩ đó hoàn toàn là REST, một danh sách thông tin là một tài nguyên riêng.
Luc Franken

Đừng cố gắng áp dụng một cách nghiêm túc (mù quáng) các câu Fielding về REST. Tất nhiên ông là cha đẻ của kiến ​​trúc REST, nhưng hãy cẩn thận: Kiến trúc REST dành cho các hệ thống có khả năng mở rộng cao, đó là lý do tại sao nó đã được suy luận từ web. Nếu nó có ý nghĩa để sử dụng một mảng của đối tượng cho vấn đề hiệu năng, thì hãy đi cho nó.
AilurusFulgens

HAL + json thường được coi là RESTful. Nó bao gồm cả phiên bản rút gọn (tóm tắt) của các đối tượng cộng với một liên kết đến toàn bộ tài nguyên.
RubberDuck

Câu trả lời:


7

Có thực sự không có cách thực sự RESTful nào khác để có được dữ liệu bạn cần trong 1 hoặc 2 yêu cầu không?

  • Không thực sự
  • Nhưng đừng nghĩ quá nhiều

Như thường lệ, khi nghĩ về REST, hãy nhớ rằng có một triển khai tham chiếu (web trên toàn thế giới) mà bạn có thể kiểm tra.

Hãy xem xét cổng thông tin Amazon - khi tôi mở dấu trang đó với bộ đệm trống, tôi thấy trình duyệt của mình thực hiện yêu cầu tới 275 tài nguyên.

Tôi có nhận được độ trễ tốt hơn nếu tất cả trạng thái đó được tải trong một tải trọng không? Đúng.

Nó sẽ mở rộng quy mô? nó sẽ quy mô web? Chắc là không. Đó là 4,5 MB dữ liệu không thể chia sẻ vì bao gồm 1KB dành riêng cho hồ sơ của tôi. Nếu đồng nghiệp của tôi ở bàn làm việc bên cạnh tôi cũng đến Amazon, cô ấy sẽ lấy cùng một dữ liệu trên mạng.

Phân tách tải trọng đó thành các tài nguyên có thể định địa chỉ riêng lẻ và đột nhiên mọi thứ trở nên tốt hơn rất nhiều - mỗi chúng tôi vẫn nhận được 1KB cá nhân hóa và mỗi chúng tôi vẫn có bản sao lưu trữ cục bộ 4,5 MB, nhưng chúng tôi không cần phải đập mạng cũng khó, bởi vì hầu hết các yêu cầu của chúng tôi được phục vụ bởi bộ đệm chia sẻ cục bộ, thay vì cần định tuyến qua internet.

Ngoài ra, hãy nhớ rằng bạn không thực sự có vấn đề với nhiều tài nguyên , bạn có vấn đề với nhiều yêu cầu . Điều đó có thể được giảm thiểu bằng cách sử dụng Lời hứa đẩy HTTP / 2.0 , với máy chủ chủ động đẩy các biểu diễn có thể được lưu vào bộ đệm. Có thể - một máy chủ không trạng thái không biết máy khách đã lưu vào bộ đệm gì và TLS gợi ý rằng bộ nhớ đệm tại các trung gian không phải là ưu tiên ....

Điều này có nghĩa là nếu bạn cần, giả sử, truy vấn danh sách 100 người dùng đã đăng nhập gần đây nhất và hiển thị tên và email của họ, trước tiên bạn cần thực hiện truy vấn GET cho danh sách kết quả, về cơ bản (về cơ bản ) là danh sách các thành phần liên kết, với mỗi đối tượng liên kết chứa URI của tài nguyên người dùng. Sau đó, bạn sẽ cần thực hiện thêm 100 yêu cầu GET - một yêu cầu cho mỗi tài nguyên người dùng - trước khi bạn thực sự có dữ liệu bạn cần để hiển thị kết quả của mình.

Tất nhiên, nếu bạn đang làm điều này trong html, đại diện của người dùng đăng nhập gần đây nhất có thể là một tài liệu với danh sách hoặc bảng tên và địa chỉ email và liên kết đến các tài nguyên đó. Ta-da.

Đừng để mất dấu vết của quan sát này bằng cách Fielding.

Điều đó không có nghĩa là tôi nghĩ mọi người nên thiết kế hệ thống của riêng mình theo phong cách kiến ​​trúc REST. REST dành cho các ứng dụng dựa trên mạng tồn tại lâu dài trải rộng trên nhiều tổ chức. Nếu bạn không thấy sự cần thiết cho các ràng buộc, thì đừng sử dụng chúng.

BIÊN TẬP

Tôi có thể đưa ra lập luận tương tự cho biểu diễn JSON không? tức là, nếu tài nguyên được đề cập là "100 người dùng đã đăng nhập lần cuối" thay vì kết quả của truy vấn được tham số hóa, thì tôi có thể trả lại dữ liệu thay vì liên kết tài nguyên không? nếu không thì tại sao? Tại sao JSON về cơ bản khác với HTML về vấn đề này?

Chúng giống nhau như thế nào: đóng gói thêm dữ liệu vào "danh sách kết quả" giúp bạn tiết kiệm chi phí cho các yêu cầu bổ sung, đồng thời ảnh hưởng đến tỷ lệ. Loại phương tiện cụ thể bạn đang sử dụng cho đại diện không thành vấn đề - ít nhất, theo như tôi biết.

Chúng khác nhau như thế nào: HTML là định dạng hypermedia và JSON không - bất kỳ triển khai máy khách tiêu chuẩn không quen thuộc nào với thông số HTML sẽ biết cách tìm các liên kết trong tài liệu HTML, hỗ trợ các tùy chọn như tìm nạp trước. JSON không có tiêu chuẩn hóa đó - bạn cần thông tin ngoài luồng về cấu trúc dữ liệu để hiểu vị trí của các liên kết trong một biểu diễn JSON. HAL sẽ phù hợp hơn với HTML về vấn đề này; sự khác biệt chính giữa HAL và HTML là việc áp dụng; HTML có khởi đầu 20 năm?

Để biết thêm thông tin chi tiết, bạn cũng có thể xem xét xem lại Định dạng cung cấp nguyên tử , mô tả cả Mục nhập và Nguồn cấp dữ liệu (danh sách các mục nhập), đặc biệt là các quy tắc cho nguyên tử: mục nhập , có thể được truy cập thông qua tài nguyên độc lập hoặc thông qua tài nguyên nguồn cấp dữ liệu.


1
Đoạn cuối đó của Fielding nên được in trên trán của tất cả các giáo viên REST trong văn bản ngược lại, để họ có thể nhìn thấy nó mỗi khi họ nhìn vào gương.
Robert Harvey

câu trả lời tuyệt vời như bình thường. re: đoạn cuối cùng của bạn về một đại diện HTML, tôi có thể đưa ra lập luận tương tự cho một đại diện JSON không? tức là, nếu tài nguyên được đề cập là "100 người dùng đã đăng nhập lần cuối" thay vì kết quả của truy vấn được tham số hóa, thì tôi có thể trả lại dữ liệu thay vì liên kết tài nguyên không? nếu không thì tại sao? Tại sao JSON về cơ bản khác với HTML về vấn đề này?
Giô-na

@Jonah JSON không phải là định dạng hypermedia, trái ngược với HTML (và một số khác). Một định dạng hypermedia cho phép mô tả các liên kết và quan hệ. Trong HTML, bạn làm điều này với <a href="URI" rel=""><form method="post">ví dụ. Trong JSON bạn không thể, trừ khi bạn sử dụng nó trong một cách đặc biệt, bởi vì JSON không xác định bất cứ điều gì về hypermedia (một số ví dụ về ad-hoc hypermedia sử dụng trong JSON: _link : [ ... ], links : [ ... ] , _link_ : [ ... ], vv) (PS: câu trả lời tuyệt vời)
AilurusFulgens

@AilurusFulgens, chắc chắn, tôi nên đã được cụ thể hơn. tôi có nghĩa là một cái gì đó như "hal + json" (hoặc bất kỳ định dạng hypermedia dựa trên JSON nào khác) - lực đẩy của câu hỏi là như nhau: tại sao trả lại một "tài liệu" trong HTML với tất cả dữ liệu, nhưng không làm tương tự trong định dạng hypermedia dựa trên JSON?
Giô-na

cảm ơn đã chỉnh sửa Vì vậy, để đảm bảo tôi hiểu bạn, nếu bạn trả về tất cả các kết quả trong bảng HTML, thay vì nói một <ul>liên kết có thể nhấp, bạn sẽ thỏa hiệp chia tỷ lệ giống như khi bạn thực hiện tương đương trong phản hồi hal + json? cụ thể, phản hồi như vậy cũng sẽ không mở rộng vì kết quả trả về, có lẽ thay đổi thường xuyên, sẽ không được lưu trong bộ nhớ cache? trong khi một danh sách các liên kết là ít dữ liệu hơn, vì vậy phần không thể truy cập được nhỏ hơn? đó là ý tưởng hay còn thiếu gì nữa không?
Giô-na
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.