建筑设计REST API与整个资源的看法(architectural design for REST

2019-10-18 18:04发布

寻找一个REST API建筑设计一些输入。 我经常发现所期望的数据是跨越多个资源的视图的组合。 你会希望客户把它们结合在一起,或提供做客户端的组合的API?

例如,假设我们正在编写一个REST API的人成为通知有关事件。 有人会显示在2种方式一个一个事件的兴趣:

  • 加入该活动上经常提出一个组织,这个人有兴趣
  • 搜索,然后标记由组织通常我不会订阅运行特定事件

我可以检索所有用户的事件100通过执行以下步骤长:

  1. GET /user/100/organizations返回123
  2. GET /organizations/123/events回报[15,16,20]
  3. GET /user/100/savedevents返回[35,36]
  4. GET /events/15,16,20,35,36返回所有事件

但是,这似乎相当重的客户端。 我几乎要一个客户端可以说,“给我所有该用户的有趣事件”:

GET /user/100/events

...然后要求服务器明白,它要经过所有的步骤1-4,并返回它们,或者,至少是,返回[15,16,20,35,36]使其成为2个步骤:让事件ID; 获得事件的细节。

这是否甚至意义,使跨多个资源削减这样一个看法?

编辑:为了进一步解释。 我犹豫是因为我可以看到/organizations/123/events是一个干净的资源; 如果是相同的说法/events?organizations=123 ,即“给我资源事件,其中组织= 123”。 同为/user/100/organizations

/user/100/events不是 “给我资源事件,其中组织= 123”。 这是“给我的组织注册,其中用户= 100,检索这些组织ID,然后给我的比赛时,组织= 123,然后给我savedevents其中user = 100”。

每三个步骤本身是一个干净的资源映射。 把它们放在一起显得凌乱。 但这样做,要求客户(尤其是Web客户端),找出所有的逻辑!

Answer 1:

可能有几种方法可以解决这个问题。不过,我认为,大部分的时间(如果该服务是由同一供应商管理),最好是对服务器端逻辑,并调用REST作为独立的可能彼此的(即,执行所需要的多个操作的服务器 - 正常读取从数据块的数据是存储在API资源处理的数据)。

在这个例子中,你记住谈论这意味着你的REST API会暴露一个“用户”的资源和子资源“事件”(你叫“savedevents”),他感兴趣的东西。有了这个,你就会有这样的事情:

  • POST /user/{username}/events存储新的事件(或多个事件)的用户感兴趣的
  • GET /user/{username}/events返回所有用户感兴趣的事件
  • GET /user/{username}/events/{eventid}返回特定事件的细节

要“过滤器”的用户事件每个组织(和其它滤波操作),可以使用“查询参数”:

  • GET /user/{username}/events?organization=123

因此,服务器(或API调用)将执行第1步中描述的操作在第4步GET /user/{username}/events 。 您还可以使其他资源(“组织”和“事件”)的API中,但他们会在其他情况下(如商店新的事件或组织等)一起使用。

HTH



Answer 2:

我有点被你的问题感到困惑,所以我会尝试尽可能全面,希望我会击中你需要= P答案。

我经常发现所期望的数据是跨越多个资源的视图的组合。 你会希望客户把它们结合在一起,或提供做客户端的组合的API?

在一个真正的RESTful环境数据的所有剖面图会由服务器来完成,而不是由客户端。

对于一个RESTful设计的主要原因是允许访问CRUD模型( 创建读取更新删除 ),通过使用标准的HTTP动词的方式(如GETPOSTPUTDELETE )。 存储这些方法的收益在某种会话或饼干或其他外部方法(如“给我鲍勃数据”,“给我的业务数据”,“给我从我的前两个查询数据”)变为超出该REST方法。

你要利用REST式发展的方式是找到以有意义的方式相结合的资源,以便提供一个RESTful环境中的方法调用是一致的方式; GET读取数据, POST创建数据, PUT更新数据, DELETE删除数据)。

所以,如果你通过4想做一些像步骤1我建议是这样的:

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}

然后,如果你想要的信息的交叉截面切片,你会为横截面命名资源(否则将它作为参数)。 要明确你的资源(随机仅供参考,命名您的资源,只有名词 - 不动词)。

你还问我:

为了进一步解释。 我犹豫是因为我可以看到/组织/ 123 /事件是一个干净的资源; 如果是相同的说法/事件?组织= 123,即“给我资源事件,其中组织= 123”。 同为/用户/ 100 /组织。

本质上这两个named resourcedresource + argument方法可以提供相同的信息。 典型地,我已经看到了,需要一个重要的圈定,只有当参数的RESTful设计API调用(范围请求,日期请求,数据的一些非常小单元,等等)。 如果你有数据的某些高阶分组可以分析/内省进一步那么它是一个命名的资源。 在你的榜样,我有它两个API调用,如REST风格的规范要求通过多条路径,并通过建立的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



文章来源: architectural design for REST API with views across resources
标签: rest