寻找有关REST API架构设计的一些信息。我经常发现所需的数据是跨多个资源的视图的组合。您希望客户端将它们组合在一起,还是提供一个为客户端组合的API?
例如,假设我们正在为人们编写REST API以获得有关事件的通知。有人会以两种方式之一表示对某事件感兴趣:
我可以通过以下长步骤检索用户100
的所有事件:
GET /user/100/organizations
返回123
GET /organizations/123/events
返回[15,16,20]
GET /user/100/savedevents
返回[35,36]
GET /events/15,16,20,35,36
返回所有活动但对于客户而言,这似乎相当沉重。我几乎希望客户能够说“给我这个用户的所有有趣事件”:
GET /user/100/events
...然后要求服务器了解它必须完成所有步骤1-4并返回它们,或者至少返回[15,16,20,35,36]
所以它变为2步:获取事件标识;获取活动详情。
这是否有意义,以这种方式制作一个跨多个资源的观点?
编辑:进一步解释。我犹豫是因为我可以看到/organizations/123/events
是一个干净的资源;如果与说/events?organizations=123
相同,即“给我组织= 123的资源事件”。 /user/100/organizations
也是如此。
但是/user/100/events
不“给我组织= 123的资源事件”。它是“给我组织注册用户= 100,检索那些组织ID,然后给我组织= 123的事件,然后给我savedevents用户= 100。”
这三个步骤本身就是一个干净的资源映射。将它们放在一起似乎很混乱。但是要求客户(尤其是Web客户端)找出所有逻辑也是如此!
答案 0 :(得分:2)
我对你的问题感到有点困惑,所以我会尽量做到尽可能全面,希望我能找到你需要的答案= P.
我经常发现所需的数据是视图的组合 多种资源。您是否希望客户将它们组合在一起,或者 提供一个为客户端组合的API?
在真正的RESTful环境中,数据的所有横截面视图都将由服务器完成,而不是由客户端完成。
RESTful设计的主要原因是允许访问CRUD模型(创建,读取,更新,删除< / em>)通过使用标准HTTP谓词(例如GET
,POST
,PUT
,DELETE
)。将这些方法的回报存储在某种会话或cookie或其他外部方法中(例如“给我数据为bob”,“给我关于业务的数据”,“从我的前两个查询中提供数据”)超越REST方法。
您希望利用RESTful开发的方式是找到以有意义的方式组合资源的方法,以便提供方法调用一致的RESTful环境; GET
读取数据,POST
创建数据,PUT
更新数据,DELETE
删除数据)。
因此,如果您想要执行类似步骤1到步骤4的操作,我建议使用以下内容:
GET /user/{userID}/organizations --> {return all affiliated organizations}
GET /user/{userID}/events --> {return all events associated with userID}
GET /organizations/{organization}/events --> {returns all eventID's assoc. with organization}
GET /user/{userID}/savedevents --> {return all eventID's userID saved to their profile}
GET /events/?eventID=(15,16,20,35,36) --> {return all of the events details for those eventID's}
GET /events/{eventID}--> {return events details for {eventID}}
您可能还有:
GET /events/ --> {return a complete listing of all event ID's}
GET /events/{userID} --> {return all events userID is associated with}
POST /event/ --> {create a new event - ID is assigned by the server}
POST /user/ --> {create a new user - ID is assigned by the server}
PUT /user/{userID} --> {update/modify user information}
然后,如果您想要横截面的信息切片,您将获得横截面的命名资源(否则将其作为参数传递)。明确您的资源(随机FYI,仅将您的资源命名为名词 - 不是动词)。
您还问:
进一步解释。我的犹豫是因为我可以看到如何 / organizations / 123 / events是一个干净的资源;如果是相同的 说/ events?organizations = 123,即“给我资源事件在哪里 organizations = 123“。/ user / 100 / organizations。相同。
基本上,named resourced
和resource + argument
方法都可以提供相同的信息。通常,只有在需要重要描述(范围请求,日期请求,一些非常小的数据单元等)时,我才会看到RESTful设计API调用参数。如果您有一些更高阶的数据分组, CAN BE 进一步解析/反省,那么它就是一个命名资源。在你的例子中,我有两个API调用,因为RESTful规范要求通过多个路径提供数据并使用已建立的HTTP方法。但是,我也会扩展一下......
/events?organizations=123 --> {return the eventID's associated with org=123}
/organizations/123/events --> {return event DETAILS for events associated with org=123}
通过Apigee
读取/读取此内容答案 1 :(得分:0)
可能有几种方法可以解决这个问题...但是,我认为大多数情况下(如果服务由同一个提供程序管理)最好在服务器端使用逻辑并进行REST调用尽可能彼此独立(即,服务器执行所需的多个操作 - 通常从存储API资源中处理的数据的DB中读取数据)。
在这个示例中,您谈到这将意味着您的REST API将公开他感兴趣的“用户”资源和子资源“事件”(您称之为“savedevents”)。考虑到这一点,您将拥有像这样的东西:
POST /user/{username}/events
存储用户感兴趣的新事件(或多个事件)GET /user/{username}/events
返回用户感兴趣的所有事件GET /user/{username}/events/{eventid}
返回特定活动的详细信息要“过滤”每个组织的用户事件(以及其他过滤操作),您可以使用“查询参数”:
GET /user/{username}/events?organization=123
因此,服务器(或API调用)将执行您在GET /user/{username}/events
中从步骤1到步骤4描述的操作。您仍然可以在API中创建其他资源(“组织”和“事件”),但是它们将在其他上下文中使用(例如存储新事件或组织等)。
HTH