我目前正在为现有的PHP应用程序设计API,为此我正在研究REST作为一种合理的架构方法。
我相信我对关键概念有一个合理的把握,但我很难找到任何已经解决过对象层次结构和REST的人。
这是问题......
在[application]业务对象层次结构中,我们有:
Users
L which have one-to-many Channel objects
L which have one-to-many Member objects
在应用程序本身中,我们使用延迟加载方法根据需要使用这些对象的数组填充User对象。我相信OO术语这是对象聚合,但我已经看到各种命名不一致,并且不关心开始关于精确命名约定的战争。
现在,请考虑我有一些松散耦合的对象,根据应用需要,我可能/不会填充。
从REST的角度来看,我试图确定方法应该是什么。这是我目前的想法(暂时只考虑GET):
选项1 - 完全填充对象:
GET api.example.com/user/{user_id}
读取User对象(资源)并返回User对象,其中包含预先加载和编码的所有可能的Channel和Member对象(JSON或XML)。
PROS:减少对象数量,不需要遍历对象层次结构 缺点:对象必须完全填充(昂贵)
选项2 - 填充主要对象并包含指向其他对象资源的链接:
GET api.example.com/user/{user_id}
读取用户对象(资源)并返回用户对象填充的用户数据和两个列表。
每个清单都引用了适当的(子)资源,即
api.example.com/channel/{channel_id}
api.example.com/member/{member_id}
我认为这接近(或确切地说)超媒体的含义 - 客户可以根据需要获得其他资源(只要我明智地标记它们)。
PROS:客户端可以选择加载下属或者以其他方式更好地分离对象作为REST资源 缺点:获得二级资源需要进一步的旅行
选项3 - 启用递归检索
GET api.example.com/user/{user_id}
阅读User对象并包含指向子对象列表的链接,即
api.example.com/user/{user_id}/channels
api.example.com/user/{user_id}/members
/ channels调用将返回表单中的频道资源列表(如上所述):
api.example.com/channel/{channel_id}
PROS:主要资源暴露了去哪里获得subodinates而不是它们是什么(更多RESTful?),没有要求预先让下属,下级列表生成器(/ channels和/ member)提供接口(方法)喜欢)使响应更像服务 缺点:现在需要三个调用才能完全填充对象
选项4 - (重新)考虑REST的对象设计
我正在重新使用[现有]应用程序对象层次结构并尝试将其应用于REST - 或者更直接地,为它提供API接口。
也许REST对象层次结构应该是不同的,或者新的RESTful思想可能会暴露现有对象设计的限制。
对上述任何想法表示欢迎。
非常感谢
保
答案 0 :(得分:39)
没有理由不将这些结合起来。
api.example.com/user/{user_id}
- 返回用户代表api.example.com/channel/{channel_id}
- 返回频道代表api.example.com/user/{user_id}/channels
- 返回频道表示列表api.example.com/user/{user_id}/channel_list
- 使用以上链接返回频道ID列表(或指向其完整陈述的链接)如果有疑问,请考虑如何在没有“API”问题的情况下向人类用户显示数据:用户需要索引页面({user_id}/channel_list
)和完整视图({user_id}/channels
)。 / p>
一旦你拥有了它,只需支持JSON而不是(或除了)HTML作为表示格式,并且你有REST。
答案 1 :(得分:25)
我能给出的最好建议是尽量避免将REST api视为暴露对象。您创建的资源应该支持您需要的用例。如有必要,您可以为所有三个选项创建资源:
api.example.com/completeuser/{id}
api.example.com/linkeduser/{id}
api.example.com/lightweightuser/{id}
显然我的名字有点傻,但你称之为无关紧要。我们的想法是您使用REST api以最合理的方式为特定使用场景提供数据。如果有多个方案,请根据需要创建多个资源。我更喜欢将我的资源视为UI模型而不是业务实体。
答案 2 :(得分:9)
我建议Restful Obects这是暴露域模型的宁静
的标准Restful Objects的想法是为域对象模型提供标准的通用RESTful接口,使用JSON公开其结构的表示,并使用HTTP GET,POST,PUT和DELETE启用与域对象实例的交互。
根据标准,URI将如下:
还有其他资源
规范定义了一些主要表示形式:
这很有趣,因为您会看到表示完全是自描述的,这样就可以在需要时实现通用查看器的实现。
或者,表示可以由定制应用程序直接使用。
答案 3 :(得分:6)
以下是我在几个小时内搜索的结论以及响应者的意见:
如果我有一个实际上是多部分对象的对象,我需要将其视为单个资源。因此,如果我获取对象,则应该存在所有子坐标。这是资源可缓存所必需的。如果我部分加载对象(并提供ETag标记),那么其他请求者可能会在他们期望一个完整的对象时收到它。 结论 - 如果对象可以作为资源使用,则应该完全填充对象。
关联对象关系应该作为其他(主要)资源的链接提供。通过这种方式,可以通过遍历API来发现对象。
此外,对主应用程序站点有意义的对象层次结构可能看起来不是您需要以RESTful方式执行的操作,但更有可能揭示现有层次结构的问题。说到这一点,API可能需要比以前设想的更专业的用例,并且可能需要专门的资源。
希望能帮到某人