我目前正在为一款现有的PHP应用程序设计API,为此正在研究REST作为一种合理的架构方法。
我相信我对关键概念有一个合理的掌握,但我很难找到任何处理对象层次结构和REST的人。
以下是问题所在...
在[应用程序]业务对象层次结构中,我们有:
Users
L which have one-to-many Channel objects
L which have one-to-many Member objects
在我们的应用程序中,我们采用一种延迟加载的方法,根据需要用对象数组填充用户对象。在面向对象的术语中,我认为这是对象聚合,但我看到了各种不一致性的命名,不想开始关于精确命名约定的争论。目前,考虑我有一些松散耦合的对象,根据应用程序需要可能会或可能不会进行填充。
从REST的角度来看,我正在尝试确定应该采取什么方法。就目前而言,以下是我的当前想法(仅考虑GET):
选项1-完全填充对象:
GET api.example.com/user/{user_id}
读取用户对象(资源),返回已经预加载和编码(JSON或XML)所有可能的频道和成员对象的用户对象。
优点:减少了对象数量,不需要遍历对象层次结构
缺点:对象必须完全填充(代价高昂)
选项2 - 填充主要对象并包含其他对象资源的链接:
GET api.example.com/user/{user_id}
读取用户对象(资源)并返回已填充用户数据的用户对象和两个列表。
每个列表都引用相应的(子)资源,例如:
api.example.com/channel/{channel_id}
api.example.com/member/{member_id}
我认为这很接近(或完全符合)超媒体的含义-客户端可以根据需要获取其他资源(只要我正确标记它们)。
优点:客户端可以选择加载下属资源或者不加载,更好地将对象分离为REST资源。
缺点:需要进一步旅行才能获取次要资源。
选项3-启用递归检索
GET api.example.com/user/{user_id}
读取用户对象并包含指向子对象列表的链接,例如:
api.example.com/user/{user_id}/channels
api.example.com/user/{user_id}/members
/channels调用将以上述形式返回频道资源列表:
api.example.com/channel/{channel_id}
优点:主要资源公开了如何获取下属的位置,但不会暴露它们是什么(更符合RESTful?),不需要一开始就获取下属,下属列表生成器(/channels 和 /members)提供了接口(类似方法),使响应更像服务。
缺点:现在需要三次调用才能完全填充对象。
选项4 - 重新考虑REST的对象设计
我正在重复使用[现有]应用程序对象层次结构,并尝试将其应用于REST - 或者更直接地为其提供API接口。
也许REST对象层次结构应该不同,或者新的RESTful思想正在暴露现有对象设计的局限性。
欢迎对以上内容进行思考。