【问题标题】:REST API - Returning a list of resources with different dataREST API - 返回具有不同数据的资源列表
【发布时间】:2016-05-27 05:00:16
【问题描述】:

我试图找出映射我在 REST API 上的几个用例的最佳方式。 我有 2 个资源/实体:用户和组织

一个组织包含多个用户(一对多关系)。

我有 2 个不同的用例:

  1. 检索没有任何用户的所有组织的列表(在这种情况下不需要用户数据)
  2. 检索所有组织及其所有关联用户的列表

所以我将第一个映射到GET /api/Organization

在 REST 标准中映射第二个的通用好方法是什么? 我需要在一个请求中获取所有内容,不能发送新请求来获取每个组织的用户列表,因为性能方面会很糟糕。

我想到了 3 种不同的可能性:

1) 类似的东西:GET /api/Organization/customlist/with-users

我真的不喜欢这个,因为它不是真正的 REST 标准,并且会与子资源混淆。

2) 为此使用查询参数:GET /api/Organization?getusers=true

这更简洁,但我也不太喜欢它,因为我更喜欢保留查询参数以仅用于过滤、分页和排序目的。

3) 在 GET 正文中使用 JSON 对象并在两个用例中使用 GET /api/Organization

然后根据 JSON 对象的内容,我会知道是否应该获取用户列表。我实际上最喜欢这种方法,因为它允许我对两个请求使用相同的路径,但我知道普遍的共识似乎是在 GET 请求上使用正文是一种不好的做法,尽管最近这似乎有使用这种方法在 ElasticSearch 等一些流行项目中变得更加普遍。

是否有处理类似案件的标准化方式?我可能错过的任何其他方式?当然,我可以让它与其中任何一个一起使用,但我试图了解对于我认为应该是常见场景的事情的最佳实践。

【问题讨论】:

    标签: java rest


    【解决方案1】:

    我的第一个想法是将组织定义为始终返回用户数据,以保持简单和一致。

    假设有特定原因这是不可能的,您可能会采用的一种方法是对每种情况使用特定的content types,并允许单个端点支持多种类型 - 所以一种类型可能是用于请求“点亮”没有用户数据的组织表示,另一个请求“完整”的包含用户数据的组织规范。

    客户端可以使用accept headers 来指定他们想要的内容类型,许多 REST 实现库支持为给定内容类型指定处理程序

    【讨论】:

      【解决方案2】:

      免责声明:这篇文章应该是评论而不是答案,但由于格式/大小问题,我将其作为答案。

      使用选项 2。您不必维护查询参数以供以后使用,一旦您已正确实施模型并查看查询参数。我还建议不要使用 QP,例如:getusers=true,而是使用通用 qp,例如 ?includeChild=users; or ?expand=users

      使用这种方式,你是未来的证明与更多的孩子/多层次的主细节关系例如,如果明天你可能需要用户下的地址,那么你可以做?show(or includeChild)=users,address等等。您还可以包含通用扩展值 ?show=all 以包含所有子项。

      我还假设当您“不”包括组织中的“用户”时,您可以通过任何方式提供“用户”的链接,以响应用户/客户的自动下钻。类似的东西:(伪结构)

      {
       Organizations:
       {
        Org1:
        {
           details..
           org1.self link (e.g if anyone just want to fetch one item of organizations) like /organizations/1
           org1.child1.link  i,e /organizations/1/users
      
        }
       }
      }
      

      通过在组织详细信息中仅提供子链接,默认情况下,您可以为用户提供链接以获取子信息。

      这就是更好的休息设计的方式。我假设。

      【讨论】:

        【解决方案3】:

        在 REST 标准中映射第二个的通用好方法是什么?

        REST 不在乎你如何拼写你的 URI。 REST 不在乎您使用了多少个 URI。 REST 不在乎您使用多少不同的 URI 来表示域模型中的“相同”实体。

        请记住,在 REST 架构风格中,大多数 URI 都是被发现的(而不是书签/永久链接)。

        但是(实际上)没有人这样做。所以我们继续……

        Cool URI don't change -- 您要小心将 REST 端点与域模型耦合得太紧,因为这会增加修改模型的成本。您应该能够改进您的域实现,而不必更改您的 API。

        因此,我建议您为修改域中实体的资源保留部分 URI 命名空间,并在命名空间的单独部分中进行花哨的报告

        /model/organization/{organizationid}
        
        vs
        
        /reports/activeOrganizationsDigest?asOf=2016-05-27
        /reports/activeOrganizations/showUsers?activeSince=2015-12-12
        

        URI 便宜;不要觉得你需要对他们小气。

        /userStories?asA=marketingStrategist&iWantTo=reviewCurrentOrganizations&soThat=iCanPlanNewCampaigns
        /userStories?asA=emailScammer&iWantTo?mineEmailAddresses&soThat=iCanBroadcastMoreSpam
        

        Ceci n'est pas une pipe

        Fielding 记录的网络成功的部分原因在于,将标识符与表示分离提供了灵活性,使网络不仅仅是一个静态文档传输应用程序。

        这首歌的名字叫做 Haddocks' Eyes...

        这首歌的名字是The Aged Aged Man...

        这首歌叫做方法和手段...

        这首歌是 A-sitting on a Gate...

        Charles Lutwidge Dodgsondecoupling the name from the entity 的力量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-07-26
          • 2013-12-21
          • 2014-11-10
          • 2022-11-11
          相关资源
          最近更新 更多