REST API:对象列表中的对象字段作为响应 JSON

REST API: fields of objects in a list of objects in response JSON

假设我们正在构建具有两个视图的单页应用程序:列表视图和详细信息视图。

在列表视图中,我们显示了一个对象列表,仅包含它们的名称,可能还有一些更简单的数据。

在详细视图中,我们展示了特定对象的所有可能字段。

因此问题来了:当我们获取 /api/items/ 时,我们应该还是不应该 JSON-encode all 列出的对象的字段,或者只是列表视图中显示的那些?

换句话说,如果我们显示像

这样的食物列表
Name     Price
Potato   1
Milk     2

我们的 API 是否需要像这样用 JSON 回应:

{ 
    [
         {
             "name": "Potato",
             "quantity": "1 kg",
             "origin": "Egypt", 
             "manufacturer": "Egypt Farmers",
             "price": 1,
             "packaging": "String bag",
             "_type": "Food"
         },
         {
             "name": "Milk",
             "quantity": "1 litre",
             "origin": "Finland", 
             "manufacturer": "Valio",
             "price": 2,
             "packaging": "Tetra Pak",
             "_type": "Food"
         },
    ]
}

或者像这样:

{ 
    [
         {
             "name": "Potato",
             "price": 1,
             "_type": "Food"
         },
         {
             "name": "Milk",
             "price": 2,
             "_type": "Food"
         },
    ]
}

RESTful API 应该集中于所代表的资源,而不一定是如何使用这些资源。

在 master/detail 场景中,通常主对象将包含主对象的详细信息,并包括其详细信息列表(包括每个详细信息的 link 到 API资源。所以 /api/items/ 可能看起来像这样:

{
    items: [
       { name: 'item 1', href: '/api/items/1' },
       { name: 'item 2', href: '/api/items/2' }
    ]
}

详细信息资源将包含项目列表中单个项目的属性。所以 /api/items/{itemName} api 可能看起来像这样:

{
    name: 'item 1', 
    color: 'blue', 
    weight: 100,
    id: '/api/items/1'
}

所以这可能最接近您的第二种情况。此模型有许多优点:它可能与您的 api 正在访问的域模型相匹配,它使每个 api 非常简单且用途单一,易于扩展,甚至可以扩展到非常大列出。缺点是可能会导致客户端更加复杂。

通常的答案可能是:这完全取决于 ;)

  1. 如果连接受限或不稳定(例如 LTE 甚至 wifi 等移动连接),最好的办法是 return 填写所有字段的整个资源列表并使用两个视图上的相同数据。在我工作的公司中,我们经常采用这种方法,因为我们的后端几乎总是为移动应用程序提供数据。

  2. 第二个想法是使用一种称为字段或资源扩展的机制。通常,向端点发出请求,要 returned 的资源字段包含在该请求中:

    /api/items?fields=(name, quantity, origin, whatever)
    

    这种机制非常方便,因为您可以使用此端点为多个视图提供服务,而不会损失任何性能。

  3. 我个人会使用两个端点。一个 /api/items/ 端点内置 field/resource 扩展机制(可以扩展的字段列表有限),第二个端点 /api/items/{itemID}/ 到 return 具有所有的特定项目数据。这也是最RESTful的做法