寻找一个REST API建筑设计一些输入。 我经常发现所期望的数据是跨越多个资源的视图的组合。 你会希望客户把它们结合在一起,或提供做客户端的组合的API?
例如,假设我们正在编写一个REST API的人成为通知有关事件。 有人会显示在2种方式一个一个事件的兴趣:
- 加入该活动上经常提出一个组织,这个人有兴趣
- 搜索,然后标记由组织通常我不会订阅运行特定事件
我可以检索所有用户的事件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个步骤:让事件ID; 获得事件的细节。
这是否甚至意义,使跨多个资源削减这样一个看法?
编辑:为了进一步解释。 我犹豫是因为我可以看到/organizations/123/events
是一个干净的资源; 如果是相同的说法/events?organizations=123
,即“给我资源事件,其中组织= 123”。 同为/user/100/organizations
。
但/user/100/events
是不是 “给我资源事件,其中组织= 123”。 这是“给我的组织注册,其中用户= 100,检索这些组织ID,然后给我的比赛时,组织= 123,然后给我savedevents其中user = 100”。
每三个步骤本身是一个干净的资源映射。 把它们放在一起显得凌乱。 但这样做,要求客户(尤其是Web客户端),找出所有的逻辑!
可能有几种方法可以解决这个问题。不过,我认为,大部分的时间(如果该服务是由同一供应商管理),最好是对服务器端逻辑,并调用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
我有点被你的问题感到困惑,所以我会尝试尽可能全面,希望我会击中你需要= P答案。
我经常发现所期望的数据是跨越多个资源的视图的组合。 你会希望客户把它们结合在一起,或提供做客户端的组合的API?
在一个真正的RESTful环境数据的所有剖面图会由服务器来完成,而不是由客户端。
对于一个RESTful设计的主要原因是允许访问CRUD模型( 创建 , 读取 , 更新 , 删除 ),通过使用标准的HTTP动词的方式(如GET
, POST
, PUT
, DELETE
)。 存储这些方法的收益在某种会话或饼干或其他外部方法(如“给我鲍勃数据”,“给我的业务数据”,“给我从我的前两个查询数据”)变为超出该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 resourced
和resource + 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