API-多个请求与分离用户角色
我正在一个单页申请的前端工作,我必须列出一些学生。每个学生都附加到一个特定的API-多个请求与分离用户角色,api,rest,single-page-application,Api,Rest,Single Page Application,我正在一个单页申请的前端工作,我必须列出一些学生。每个学生都附加到一个特定的用户id这是API在我执行GET/students时为所有用户角色(超级管理员、管理员、教授、学生)返回的: { address: null class_id: 184 class_name: "I B" date_of_birth: null first_name: "first" gender: null grade: 1 id: 192 last_name: "last" n
用户id
这是API在我执行GET/students
时为所有用户角色(超级管理员、管理员、教授、学生)返回的:
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
}
我正在从事superadmin角色的工作,此时我需要每个学生的额外数据(subscription\u type
),该数据仅在GET/users/:id
因此,当我通过GET/students/
在页面上列出20-30名学生时,为了获得订阅类型
,我还需要做20-30个额外请求,每个学生一个
我和API人员谈过这件事,他们告诉我,将额外的数据包含到学生中“不是RESTful的方式”,“它会更慢响应时间”,并且“30个额外的请求比一大块还要轻”
我不知道如何使用API,所以我真的没有发言权,但我是否疯狂地认为一个页面加载上30个请求是可笑的
那么接下来呢?我是否继续执行额外的请求?他是否应该将每个用户角色的响应分开,只包括每个角色所需的内容?处理这个问题的正确方法是什么?这里有两个问题,不应该联系在一起-
一个是为索引调用(/students)的每个用户返回的数据,另一个是授权过程,该过程应确定某个用户可以公开哪些数据
关于数据问题,我认为没有具体的规则可以遵循。这完全取决于应用程序的要求。如果通常不需要订阅PysPyType字段,则可以考虑传递一个查询参数(例如“包含DeExtExoPosiDATA=1”),以指示您需要在特定请求上缺省,默认情况下它将不返回。
关于授权问题-这应该与您请求的数据完全断开。服务器应该能够根据用户id确定哪些数据对用户可见(您可以查看作为可能的解决方案)
因此,结合这两个问题,任何类型的用户都应该能够发出带有或不带有“include_extra_data”标志的“/students”请求。如果服务器发现用户未经授权无法查看额外数据,您可以选择两个选项中的一个-要么仅返回允许用户查看的数据,要么返回“401 unauthorized”响应
这两种方法都是有效的,并且会影响您在客户端应用程序上处理响应的方式。
(我个人更喜欢后者,因为后者对客户更具描述性)
希望这有帮助:)严格地说,API的人是正确的,但过于严格地遵循RESTful的原则可能会导致效率低下,比如纯粹主义实现造成的1+N问题。RESTful设计中的一个关键概念是资源不必直接映射到域对象。在设计资源时,必须考虑使用场景。在超级管理员场景中,这听起来像是当客户端请求一组学生
时,它通常或总是需要用户的数据
,特别是订阅类型
。对象模型显然是标准化的,但这并不意味着资源必须是或必须始终是标准化的
我使用了几种不同的模式来提高类似场景的效率。哪种(如果有)应用取决于客户端如何使用资源
复合资源
这是将全部或部分两个或多个域对象(例如student
和user
)组合到单个资源中
由于所有学生
可能也是用户
,因此您可以在学生资源中酌情包含全部或部分用户数据
GET/students
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
subscription_type: "foo"
}
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
}
相关资源
(类似于另一个响应)这是一种技术,客户机可以指示它希望响应中包含相关资源。这在域模型中的“has a”类型关系中特别有用。它允许客户端实质上延迟加载或急切加载资源
GET/students
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
subscription_type: "foo"
}
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
}
GET/students?include\u user=true
{
address: null
class_id: 184
class_name: "I B"
date_of_birth: null
first_name: "first"
gender: null
grade: 1
id: 192
last_name: "last"
nationality: null
place_of_birth: null
ranking_by_class: 0
ranking_by_school: 0
registration_number: null
user_id: 238
user:
{
id: 238
subscription_type: "foo"
...
}
}
在不了解实际API的情况下,REST性能方面的重要因素是组件交互。更多的交互可能会导致最终用户性能降低以及高延迟问题。因此,在没有任何API的第一手知识的情况下,它可能是一个“按你说的做,而不是按正确的做”的问题。当我说分离时,我指的是数据分离。因此,根据每个请求中包含的auth_令牌确定的用户角色,API可以为每个角色返回不同的数据集。因此超级管理员将包括用户id、订阅类型和其他用户数据,而管理员发出的相同请求将只包括个人数据。还是说一切都必须是一样的?