REST:返回复杂的嵌套数据与多个调用

Igg*_*ggY 11 javascript api rest node.js angularjs

我有一个由NodeJS服务的Ang api到AngularJS前端.

我合作users:

GET  /api/users  #Returns all users
POST /api/users  #Create  new user

GET   /api/users/:id   #Return a user
PUT   /api/users/:id   #Edit a user
DELTE /api/users/:id   #Delete a user
Run Code Online (Sandbox Code Playgroud)

这是一个用户:

{
  login : "admin"
  email : "admin@admin.com"
  pass  : "hashedpassword"
  ...
}
Run Code Online (Sandbox Code Playgroud)

我的用户可以属于 groups

GET   /api/users/:id/groups   #Return the groups of a user
Run Code Online (Sandbox Code Playgroud)

他们也可以拥有constraints或可以继承constraints他们的团体

GET   /api/users/:id/constraints   #Return the constraints of a user
GET   /api/groups/:id/constraints   #Return the constraints of a group
Run Code Online (Sandbox Code Playgroud)

问题 :

我正在创建一个管理页面,显示所有用户,他们的组,他们的约束.

我是不是该 :

  1. 在javascript(Angular)前端的for循环中发出许多请求?

就像是 :

$http.get(/api/users).then(function(result) {
  result.data.forEach(function(user) {
    $http.get('/api/users/'+user.data.id+'/groups).then(function(groups) {
      groups.forEach(function(group) {
        $http.get('/api/groups/'+group.data.id+'/constraints)
      })
    })
  })
})
Run Code Online (Sandbox Code Playgroud)
  1. 创建一个路径 /api/users/withConstraintsAndGroups

这将返回包含其组和约束的所有用户的大列表.


我发现解决方案1非常好,可维护,简单,通用,但我担心性能非常糟糕

我发现解决方案2难看,难以维护,难以编码,不通用但性能良好

我应该选择哪种解决方案?

Ido*_*dos 6

你的问题基本归结为:

哪个更好,一个大的HTTP请求,或许多小的请求?

要记住的一件事是客户端和服务器之间的预期网络延迟(ping时间).在具有良好带宽的高延迟情况下,许多小请求将比一个大请求表现得得多.

此外,有一个大请求可以提高压缩响应的效率,并避免额外的HTTP请求和响应头的开销.

说了这么多,我仍然建议你选项1 开始,完全是因为你声明你很容易编码.然后看看它是否符合您的要求.如果没有,那么尝试选项2.

作为最后一点,我通常更喜欢对很多小请求提出一个大请求,因为这样可以很容易地将每个请求定义为完全应用或回滚的事务.这样我的客户端就不会遇到一些状态,其中一些小的请求成功而另一些则失败,并且他们现在的API提供的数据本地副本不一致.


Cos*_*min 6

接下来,基于论文的结果几乎相同,多个请求与一个大规模请求相比,性能成本是多少.我们在2016年,除非您处理的互联网连接不佳,否则您应该通过提出多个请求来实现.

您正在为全球99%的人口或使用Opera的1%部分(用于turbo功能)开发您的应用程序?

此外,如果我们正在讨论设计RESTapi,那么保持一致可能是这种API的主要思想.在您的情况下,如果您编写第二种方法,则必须在代码的其余部分中编写类似的内容,以保持所有控制器的一致性,这是无法完成的.

Also, an API is an API and should not be modified when a front end application is being built on that API.当您有10个请求API的应用程序时,请考虑这种情况,但您遇到的情况与此相同,但每个应用程序都需要不同的响应.您要为API添加新方法吗?这是一个不好的做法

RESTapi中的路由应该根据您拥有的逻辑资源(可以使用HTTP谓词操作的对象)进行:

例子:

 * when you have a relation between entities

     /users/3/accounts       // should return a list of accounts from user 3
     /users/3/accounts/2     // should return account 2 from user 3

 * custom actions on your logical resources

    /users/3/approve
    /accounts/2/disable
Run Code Online (Sandbox Code Playgroud)

另外一个好的API应该能够提供partial requests(例如向常规请求添加一些查询字符串参数:users/3?fields=Name,FirstName)versioning,documentation(在这种情况下apiDocs.js非常有用),相同的请求类型(json)pagination,token authcompression(我从来没有做了最后一个:))


lor*_*non 5

我建议修改用于为用户资源提供服务的端点,以接受(通过查询参数)应将哪些相关资源包含为响应的一部分:

/api/users?includes=groups&includes=constraints
Run Code Online (Sandbox Code Playgroud)

这是一个非常灵活的解决方案,如果您的需求在未来扩展,您可以轻松支持更多相关资源。

如果您关心如何构建响应,我建议您查看JSON:API

使用的一个优点JSON:API是,如果多个用户共享相同的组/约束,那么您将不必获取同一实体的多个表示。


小智 0

在我看来,管理页面的性能并不是一个太大的问题。两者之间的唯一区别是,在 #1 中您有 3 个 api 调用,而 #2 只有 1 个。数据应该是相同的,数据应该是合理的,而不是极大的。因此,如果#1 更容易编码和维护,那么您应该选择它。您不应该有任何性能问题。