当前位置: 首页 > 知识库问答 >
问题:

REST API设计用于单个调用中多个收集的最佳实践

鲍向笛
2023-03-14

我有两个资源/users/products,我可以用/users/{id}/products检索用户的产品。这很简单,我会返回一个JSON响应,如下所示:

{
   "items": {
      ...
   }
}

现在,如果我想同时获得用户和他们的产品,该怎么办?我知道我可以使用?expand=products/users/{id}调用并返回如下数据:

{
   "item": {
      ...
      "products": {
          ...
      }
   }
}

但这是最佳实践吗?还是退回这样的东西更好:

{
   "user": {
      "item": {
         ...
      }
   }
   "products": {
      "items": {
         ...
      }
   }
}

所以我的问题是:

  1. 在一次呼叫中返回多个数据收集的最佳实践是什么

共有3个答案

赏航
2023-03-14

我想你的问题的答案可能在幻灯片75到77中,这些幻灯片与你引用的视频相关(http://www.slideshare.net/stormpath/elegant-rest-design-webinar).

我相信在这种情况下,另一个好的(类似的)方法是定义一个更高级别的复合资源(如“帐户”、“用户产品”等)。)包含您需要的两个子资源,有点像它们的容器。例如:

{
    "account" : {
       "id" : "123",
       "user": {
          "items": {
             ...
          }
       }
       "products": {
          "items": {
             ...
          }
       }
    }
}

它们做的事情与您在幻灯片中看到的类似,它们创建“容器”资源,但不是嵌入集合数据,而是提供指向各个集合的链接。

但我不确定多个系列是否最适合您提供的示例。在您的情况下,我认为可以从/users/{id}/products返回整个产品列表,并简单地标记该用户实际拥有的产品(非拥有的产品被解释为可供该用户使用),例如:

{
    "user" : {
       "id" : "123",
       "products": [{
          "id" : "A456",
          "owns" : true,
          "details": {
             ...
          }
       }]
    }
}

您甚至可能想要控制结果中是否出现“非所有”项,例如:

/users/{id}/products?ownership=all

换句话说,“给我给定用户可用的产品列表,并标记他们实际拥有的产品。”

/users/{id}/products?ownership=owned

同样,“只给我给定用户实际拥有的产品。”

在REST面向资源的体系结构样式中,查询参数适用于选择(也就是搜索;哪些行)、分页(多少)、排序(哪个顺序)和投影(哪些列)。

所有权查询参数适合选择/搜索类别。

魏安宁
2023-03-14

包含其他数据的常用方法如下(您的第二个示例):

{
    "users: [
        {
            ...
            "products": [
                {
                    ...
                }
            ]
        }
    ]
}

如果你通常将结果包装在一个“items”容器中,我只会为用户做这件事,但我已经看到两个结果都包装在一个容器中。我认为没有真正的共识,但我倾向于第一个。作为旁注,因为您在问题中提到了它,所以我不会在“项”/“项”之间切换,因为这会破坏为您的数据提供通用容器的目的。而是始终使用项目,如果只有一个项目,则将其作为数组返回。

你是否应该包括项目取决于。由于对包含的项目进行分页是不可行的,我倾向于不允许包含,因为可能会有很多项目被退回。例如(用户拥有的产品),如果它指的是来自供应商的产品(例如目录中的产品),我可能不会使用它,但如果它是某种购物车,我也可以。

司寇高洁
2023-03-14

对我来说,这听起来像是/users/{id}/products/users/{id}?expand=products是一样的,所以我会坚持使用第一个(非查询字符串)来保持URL的一致性。然后以以下格式返回数据:

{
    username: "Dave",
    userid: 123,
    products: [
        {
            productname: "amazing product",
            productid: "ab123"
        }
    ]
}

用户的产品显然是用户的子数据

对于问题2,我应该使用多个endpoint还是只使用一个endpoint,根据构建资源的方式(如果资源索引/缓存良好,可能会“更便宜”)、是否存在安全风险、每个项目实际使用的数量等进行调用。

 类似资料:
  • 当多次调用保存时,它可以工作,但需要几分钟。 在我的理解中,保存执行。 因此,如果我可以将放在一起,则需要更短的时间。 有没有这方面的做法?

  • 我必须运行多个外部调用操作,然后以列表的形式获得结果。我决定使用api,而我准备的代码相当恶心: 示例: 我有以下几个问题: > 我可以避免在流中重复块吗?在流中我将CompletableFuture映射到User? 此代码是否可以不那么连续(如何避免等待所有的未来完成?) 这样做可以吗(所有的未来都将在流中解决吗?):

  • 由于我不想多次使用流来单独收集每个属性,也不想使用来收集每个属性,是否有任何方法可以用单个流来获得上述属性。

  • 本文向大家介绍分享20个数据库设计的最佳实践,包括了分享20个数据库设计的最佳实践的使用技巧和注意事项,需要的朋友参考一下 数据库设计是整个程序的重点之一,为了支持相关程序运行,最佳的数据库设计往往不可能一蹴而就,只能反复探寻并逐步求精,这是一个复杂的过程,也是规划和结构化数据库中的数据对象以及这些数据对象之间关系的过程。下面给出了20个数据库设计最佳实践,当然,所谓最佳,还是要看它是否适合你的程

  • 问题内容: 今天,我在登录表单后面添加了额外的安全检查,以减缓暴力攻击。我有多个登录表单,并提供了一个易于调用的函数,该函数可以进行所有检查,然后返回结果。 问题是结果不是单个值,结果包括: 为此,我创建了一个新类。这一切都很好。 但是我经常有方便的实用程序函数,这些函数会返回多个值,并开始发现每次为结果创建一个新类都有些烦人。 有没有更好的方法来返回多个值?还是我只是懒惰?:) 问题答案: 不,

  • 问题内容: 我有一套清单: 我要s1∩s2∩s3 … 我可以编写一个函数来执行一系列成对的操作,等等。 有没有推荐,更好或内置的方法? 问题答案: 从python版本2.6开始,您可以对使用多个参数,例如 如果这些集合在列表中,则表示为: 这里是列表扩展 请注意,是 不是 一个静态的方法,但这种使用功能符号应用第一套交叉口列表的其余部分。因此,如果参数列表为空,则将失败。