Thiết kế phần còn lại - Nhiều cuộc gọi so với trả lại tất cả dữ liệu trong một cuộc gọi


8

Tôi đang cố gắng xây dựng một API còn lại cho một ứng dụng Android. Giả sử tôi có một usersbảng với (id, name, email)và một songsbảng với (id, song_name, album)và một hiệp hội tham gia phong phú giữa chúng như streams(user_id, song_id, listen_count). Tôi muốn tìm nạp thông tin chi tiết về tất cả các luồng và hiển thị nó trong ứng dụng dưới dạng danh sách. Danh sách sẽ hiển thị tên bài hát, tên album, tên người dùng và số lượt nghe. Tôi thấy ba lựa chọn hợp lý -

  1. GETđến /streamsvà lấy một danh sách của tất cả song_idsuser_ids. Sau đó hãy GETđến /user/:id/song/:idcho mỗi người dùng và bài hát id để có được những người dùng và thông tin bài hát.
  2. GETđến /streamsvà lấy một danh sách của tất cả user_idssong_ids. Rồi một GETđến /user?ids=<comma_separated_ids>để lấy thông tin về tất cả những người sử dụng và một GETđể song?ids=<comma_separated_ids>để lấy thông tin về tất cả các bài hát.
  3. GETđến /streamsvà lấy mọi thứ trong một cuộc gọi. Cái gì đó như -

    [
    
      {
    
        "user_id" : 10,
        "song_id" : 14,
        "listen_count" : 5,
        "user" : {
          "id"     : 10,
          "name"   : "bla", 
          "email"  : "bla",
        },
        "song" : {
          "id"     : 14,
          "name"   : "blu",
          "album"  : "blu"
       }
      },
    ...
    ]
    

Tôi muốn đi với tùy chọn 3 vì nó mang lại cho tôi mọi thứ trong một cuộc gọi, nhưng tôi không nghĩ nó rất đầy đủ và tôi sợ rằng nó sẽ không thể mở rộng được. Tùy chọn 2 là tốt nhưng phải mất 3 cuộc gọi, điều đó có nghĩa là thời gian tải danh sách đáng kể. Và tùy chọn 1 theo phần còn lại nhưng sẽ nhận được nhiều cuộc gọi để hiển thị danh sách và thực hiện nhiều cuộc gọi từ thiết bị di động là không khả thi.

Điều gì sẽ là cách được đề nghị để đi về điều này?


Nghỉ ngơi và có thể bán được là hai thứ khác nhau.
Robert Harvey

@RobertHarvey nghĩa là gì?
aandis

Điều gì khiến bạn nghĩ rằng chất lượng giao diện REST của bạn ảnh hưởng đến khả năng bán được của sản phẩm? Bạn đang thực sự bán giao diện REST? Nếu bạn không, không ai quan tâm những gì dưới mui xe. Xem thêm meta.stackexchange.com/q/142353
Robert Harvey

1
Có chi phí rất lớn trong việc thực hiện cuộc gọi REST. Do đó, có khả năng mạnh mẽ rằng 3 là cách tiếp cận tốt nhất từ ​​quan điểm về khả năng mở rộng, đặc biệt nếu bạn sử dụng tất cả các dữ liệu được trả về.
Robert Harvey

Câu trả lời:


6

Khi tạo giao diện REST, không có yêu cầu, hoặc thậm chí kỳ vọng, rằng các phản hồi trên giao diện REST tương ứng trực tiếp với các bảng hoặc tham gia trong cơ sở dữ liệu.

/streamsGiao diện của bạn có thể dễ dàng được thể hiện như

[
  {
    "listen_count" : 5,
    "user" : {
      "href"     : "/users/10",
      "name"   : "bla", 
    },
    "song" : {
      "href"     : "/songs/14",
      "name"   : "blu",
      "album"  : "blu"
    }
  },
  ...
]

Trong đó các đối tượng JSON chứa các chi tiết chính của người dùng và các bài hát (gần như) luôn phù hợp với người tiêu dùng của tài nguyên luồng và liên kết đến tài nguyên bài hát / người dùng có liên quan nếu cần thêm chi tiết.

Đây thực chất là một biến thể của tùy chọn thứ ba của bạn, với dự phòng cho tùy chọn 1 nếu cần thêm chi tiết.


Không có câu trả lời chắc chắn nào cho tôi ... tùy chọn 3 có thể đơn giản nếu tên miền vẫn đơn giản nhưng nó sẽ khiến bạn gặp rắc rối với các đối tượng nhìn thấy nhiều hơn hai cấp độ. Ví dụ: bạn muốn truy xuất tất cả các Khóa học có sẵn với dữ liệu của giáo viên của họ. Bạn có Course-> Teacher(thông tin về người là giáo viên, được lưu trữ trong một bảng tách biệt) -> Person(người thực tế, như bạn có thể nhớ lại cùng một người có thể là giáo viên của một số Khóa học). Tùy chọn 2 có thể mở rộng và yêu cầu * yêu cầu. Cũng chọn. 1 cũng có thể mở rộng, nhưng nó có thể cần >> yêu cầu.
Victor

Vì vậy, để tổng hợp nhận xét trên: nếu bạn tìm kiếm hiệu quả, hãy phấn đấu cho số 1, nhưng nếu bạn đang tìm kiếm một hệ thống có thể phát triển mà không gặp vấn đề về thời gian (khả năng mở rộng) mà không phải đau đầu, hãy nhắm đến tùy chọn 1 hoặc 2. Rất đáng để đề cập đến việc tối ưu hóa sớm là gốc rễ của tội ác ... vì vậy đây là cảnh báo cho lựa chọn 3.
Victor

cần sửa mình ở trên .. "nếu bạn tìm kiếm hiệu quả, thì hãy phấn đấu cho số 3"
Victor

3

Bạn chắc chắn muốn một GEThoạt động duy nhất trả về siêu dữ liệu về từng bài hát và người dùng ngoài các id mờ của chúng.

  • Như bạn đã chỉ ra, nó đơn giản hơn nhiều. Đó là một điều tốt.
  • Làm một trong hầu hết các hoạt động phổ biến đối với khách hàng của bạn các ứng dụng yêu cầu máy chủ duy nhất thay vì O (n) yêu cầu là nhiều hơn khả năng mở rộng. Về lâu dài, mạng sẽ là nút cổ chai lớn nhất của bạn, vì vậy bạn không muốn gửi bất kỳ yêu cầu nào nhiều hơn bạn phải gửi.
  • Bản thân các id là vô dụng ngoại trừ việc thực hiện các cuộc gọi REST bổ sung.
  • Miễn là siêu dữ liệu của bạn có kích thước tương đối nhỏ và giới hạn (ví dụ: không có trang văn bản mô tả hoặc tệp âm thanh thực tế nào, chỉ có tên, loại, số, v.v.) trả lại nó ngoài id không có khả năng là vấn đề về hiệu suất.

Hấp dẫn. Nhưng tùy chọn 3 không thực sự tuân thủ một rest-fullthiết kế nào? Một GETđể streams nên trả lại tất cả các streamsvà không có gì khác (ngay cả khi họ chỉ là id và vô ích cho khách hàng).
aandis

2
@zack Theo nghĩa chặt chẽ nhất, có, nhưng bất kỳ nguyên tắc thiết kế nào cũng có thể được đưa ra quá xa. Khi bạn thấy mình tranh cãi chương trình nên làm điều gì đó vô ích , đó thường không phải là một dấu hiệu tốt.
Ixrec

Siêu dữ liệu là dữ liệu về dữ liệu, đây chỉ là dữ liệu.
Jacob Raihle

@zack: Một streamstài nguyên có thể chứa (một phần) các tài nguyên khác. Những thứ thuộc về logic của một tài nguyên nên được trình bày trong phần trình bày của tài nguyên đó.
Bart van Ingen Schenau

1
@zack tùy chọn 3 hoàn toàn 100% RESTful. Tài nguyên bạn trưng ra thông qua API không có yêu cầu nào liên quan đến bất kỳ thứ gì khác trong hệ thống của bạn, bao gồm các bảng DB và mô hình miền của bạn. Bạn có thể có 3 bảng cơ sở dữ liệu và 600 tài nguyên nếu điều đó có ý nghĩa đối với ứng dụng web của bạn. Không có yêu cầu để thể hiện các mối quan hệ DB của bạn trong các mối quan hệ Tài nguyên của bạn.
Cormac Mulhall
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.