Luôn trả về các đối tượng đơn lẻ trong một mảng cho các tải trọng JSON API REST?


8

Đối với API REST mà tôi đang làm việc, tôi muốn trả về JSON theo bố cục nhất quán:

{
  "Data" : {
     "Id" : 123,
     "Email" : "charlie@somewhere.com"
     "Firstname" : "Charlie",
     "Surname" : "Brown",
 },
 "Error" : null
}

Tải trọng sẽ luôn chứa "Dữ liệu" và "Lỗi", trong đó một hoặc khác có thể là null.

Câu hỏi của tôi liên quan đến "Dữ liệu" và các điểm cuối chỉ thực sự trả về một đối tượng. Ví dụ: giả sử tôi có API users/current, trả về người dùng hiện được xác thực. Tôi đã trả lại người dùng đó như được hiển thị ở trên; một đối tượng JSON có tên là "Dữ liệu".

Đối với các điểm cuối có thể trả về 0, một hoặc nhiều đối tượng, thì tất nhiên tôi sẽ biến "Dữ liệu" thành một mảng:

{
  "Data" : [
    {
      (first object)
    },
    {
      (second object)
    }
  ],
  "Error" : null
}

Tôi đã nghe một quan điểm rằng, để thống nhất, "Dữ liệu" phải luôn là một mảng. Ngay cả khi một điểm cuối sẽ chỉ trả về một đối tượng duy nhất (hoặc null).

Người khác nghĩ gì? Tôi nghĩ rằng không cần phải tạo "Dữ liệu" và mảng nếu không bao giờ có nhiều hơn một đối tượng được trả về.


Tôi nghĩ rằng nếu có một số loại lỗi, bạn đã trả lại mã 400 hoặc 500 thích hợp và gửi bất kỳ chi tiết nào trong nội dung. Trả lại một phần cho dữ liệu có vẻ kỳ lạ và có thể gây nhầm lẫn, đặc biệt là nếu bạn có dữ liệu VÀ lỗi được đặt trong ví dụ của bạn.
Andy

Câu trả lời:


9

Tôi nghĩ rằng loại nhất quán này là sai lầm.

Việc gói dữ liệu trong một mảng không có khả năng mang lại lợi ích cho người tiêu dùng API, bởi vì anh ta vẫn sẽ phải biết cách diễn giải dữ liệu thực tế. Ví dụ, không có khả năng các kết quả "dữ liệu" của /users/current/cities/chicago/restaurantssẽ được xử lý bởi cùng một mã.

Đối với các lỗi, mặt khác, nó khả năng là tất cả các lỗi được xử lý bởi cùng một mã xử lý lỗi, và sau đó là một lợi ích để sử dụng cấu trúc tương tự.

Hãy tự hỏi mình điều này: nếu đây là một lớp trong ngôn ngữ OOP yêu thích của bạn, bạn có làm cho tất cả các phương thức trả về cùng một kiểu cho sự thống nhất không?


Tôi cũng đang nghiêng về điều này. Như bạn nói ở điểm cuối cùng của bạn, nếu tôi có một thuộc tính lớp là (giả sử) một đối tượng Người dùng, tôi sẽ không biến nó thành một thuộc tính mảng cho một số tính nhất quán được nhận thức.
Diego Barros

Làm thế nào để bạn phân biệt giữa /users/currentvà người dùng có ID (có thể là tên đăng nhập) là "hiện tại"?
TrueWill

1

Nếu bên nhận cần một người nhận chung cho các thông báo JSON của bạn, thì có thể hữu ích khi nút dữ liệu có cùng định dạng. Vì vậy, trong trường hợp này, thật hữu ích khi luôn có một mảng, vì vậy nó có thể được phân tích cú pháp theo cùng một cách mọi lúc.

Nếu mỗi phản hồi sẽ được xử lý riêng lẻ (các lệnh gọi API khác nhau từ các phương thức khác nhau), tôi có thể thấy quan điểm của bạn, tuy nhiên nó sẽ hoàn toàn rõ ràng (từ các lệnh gọi API) khi một mảng hoặc một đối tượng được trả về.


Quan điểm của bạn về nó có cùng định dạng, do đó được phân tích cú pháp theo cùng một cách mỗi lần có ý nghĩa hoàn hảo.
Diego Barros

Mặc dù, thư viện mà tôi đang sử dụng phân tích cú pháp JSON cho tôi và xử lý xem JSON là một mảng hay một đối tượng.
Diego Barros

Nhưng sau đó, mã đang sử dụng bất kỳ đối tượng nào mà thư viện của bạn đang trả về phải biết kết quả là một mảng hay một đối tượng.
Geerten

Tôi đang sử dụng RestKit, gọi hàm gọi lại đại biểu thích hợp tùy thuộc vào việc đó là một mảng hay một đối tượng: - (void) objectLoader: (RKObjectLoader *) objectLoader didLoadObjects: (NSArray *) object hoặc - (void) objectLoader: ) objectLoader didLoadObjects: (id) object. Đó là một cách tốt đẹp để làm điều đó.
Diego Barros

Đó thực sự là một cách tốt để làm điều đó, tuy nhiên không phải ai cũng có thể sử dụng một cách tinh vi tốt đẹp như vậy ..
Geerten

1

Tôi không phải là người hâm mộ cách tiếp cận mảng vì nó không mang lại sự nhất quán thực sự. Nó buộc người dùng dịch vụ phải tự hỏi về những điều như, điều gì xảy ra nếu có nhiều hơn một đối tượng trong mảng này hoặc thoát khỏi sự bao bọc mảng càng sớm càng tốt cho các mảng singleton. Bạn vẫn phải làm hai việc khác nhau.

Tuy nhiên, nếu bạn sử dụng mảng, hãy đảm bảo rằng Dữ liệu không bao giờ là null. Nếu không có dữ liệu thì mảng sẽ trống. Đó là lợi thế duy nhất tôi có thể thấy.


-1

Tôi đang rơi về phía luôn luôn trả lại một mảng. Về phía khách hàng, tôi sử dụng đối tượng phản hồi "Người dùng" của mình cho dù nhận được tất cả người dùng hay chỉ một người dùng. Nếu bạn có một điểm cuối trả về mảng và một điểm khác trả về cùng một đối tượng, nhưng không bao giờ nhiều hơn một, vẫn sử dụng một mảng.

Có các đối số tương tự cho việc sử dụng cùng một logic ở phía máy chủ, chỉ cần sử dụng cùng một mã cho dù truy vấn của bạn trả về một mục hay nhiều mục.

Ngoại lệ duy nhất sẽ là khi trả về một đối tượng không bao giờ tồn tại dưới dạng một mảng, trong bất kỳ bối cảnh nào, sau đó không có nhu cầu.


Đối với tôi, JSON đại diện cho một đối tượng (chính là nó). Vì vậy, nếu tôi đang tạo các lớp (bằng ngôn ngữ lập trình yêu thích của bạn) - giả sử tôi có một lớp Đăng nhập có thuộc tính CurrentUser - Tôi sẽ không biến thuộc tính đó thành một mảng chứa một đối tượng Người dùng. Tôi sẽ có được người dùng hiện tại với Đăng nhập. Hiện tại, và không Đăng nhập. Hiện tại [0]. Tôi không chỉ phải kiểm tra thuộc tính nullUser mà còn kiểm tra độ dài của mảng?
Diego Barros
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.