在 REST-ful api 中序列化外键字段的最佳实践是啥
Posted
技术标签:
【中文标题】在 REST-ful api 中序列化外键字段的最佳实践是啥【英文标题】:What is best practice to serialize foreign key fields in a REST-ful api在 REST-ful api 中序列化外键字段的最佳实践是什么 【发布时间】:2014-11-01 23:41:36 【问题描述】:我想用 REST-ful api 编写一个 Django 应用程序。 Django REST 框架提供了三个内置的模型序列化器: ModelSerializer 序列化成这样的东西
'normal_field': 'value',
'foreign_key_field': 42
和 HyperlinkedModelSerializer 序列化成这样的东西
'normal_field': 'value',
'foreign_key_field': 'http://domain/api/myothermodel/11'
我的问题是,是否有另一种好方法来序列化数据,以便客户端直接知道哪些字段必须解析,哪些字段不需要解析。
示例:接收此消息的客户端
'foo': 'http://domain/api/myothermodel/11',
'bar': 'http://otherdomain/api/myothermodel/12'
不知道 foo 或 bar 是否应该是可解析的外键字段而不是纯 url。比如:
'foo': 'http://domain/api/myothermodel/11', # Here the client might know that this is only a plain url.
'bar':
'_foreignkey': true, # Tells the client that this field should behave as a foreign key which has to be resolved first
'url': 'http://otherdomain/api/myothermodel/12'
是否有任何标准或最佳做法?或者最佳实践是客户端不从 JSON 中知道这一点,而是从它拥有或从服务器获取的其他代码中知道这一点?
更新: 可选,您可以添加对于 AngularJS 等一些知名客户端库的最佳实践方式。
【问题讨论】:
这实际上是一个我自己没想到的有趣问题。对我们来说,前端人员提前知道必须解决什么 您能否澄清一下您所说的必须首先解析的外键是什么意思?通过已解决,您的意思是相关实例在您的 REST API 中具有资源位置端点吗?并且通过先解决,先进行什么具体操作? 是:“解析”表示数据代表信息,获取相关实例。 “首先”表示我最终想在我的站点上显示该实例和所有相关实例。所以客户端必须遵循所有的关系并在页面被渲染之前获取实例。但是:在我的第一个示例中,数据是这种“可解析”的信息,而不仅仅是一些普通数据,这一点并不明显。这是否更清楚? 我明白了,您的目标是自描述 API,或多或少类似于 HATEOAS。 AFAIK,虽然有一些work on that front,但 JSON 还没有标准。无论您选择何种设计,记录 API 都是一个好主意。 @Fiver:谢谢。如果您将帖子设置为答案,我可以接受并(稍后)奖励赏金。 【参考方案1】:您似乎在追求一个自描述和可探索的 Web API 服务,这实际上是原始 REST 概念的核心功能,称为 Hypermedia as the Engine of Application State (HATEOAS)。本质上,符合 HATEOAS 的 Web 服务不依赖于系统资源的任何先验知识,而不是初始 URL 入口点。
这与 Service Oriented Architecture (SOA) 形成对比,其中单个服务基本上是不相关的,并且需要事先知道它们的存在才能将多个服务调用串在一起以完成具有多个可能相关资源的任务。
大多数对 REST API 的引用实际上并不完全是 RESTful,应该更准确地描述为 Web API,因为它们更符合 SOA 设计:一组指向特定实例和实例集合的 URL一种特定的类型。这还包括使用不同的 HTTP 动词(GET、PATCH、POST、PUT)来对这些资源执行各种操作。 Django REST Framework (DRF) 实际上有一个关于这个主题的页面,其中包含一些关于真正 RESTful 设计的重要资源的链接,包括 Roy Fielding 的论文:
http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas
我推测“REST API”一词的当前使用与许多开发人员的启示有关,即实现真正的 RESTful 服务绝非易事,而且在许多情况下会针对特定用例进行过度设计。也许这是“完美是善的敌人”的一个很好的例子。对于使用 AngularJS 作为通过 DRF 与 Django 后端交互的客户端框架的情况,尤其如此。 AngularJS 框架中没有任何东西可以解析真正的 RESTful 设计以自动为给定资源提供各种可能的应用程序状态。此外,javascript 和 Python 代码通常由同一个开发人员负责,因此缺乏自描述 API 并不是开发的主要障碍。
关于在 JSON 中实现真正的 RESTful API,有几个项目试图促进这一点,即Hypertext Application Language (HAL) 和JSON Linked Data (JSON-LD)。但是,我不知道 DRF 本身支持其中任何一个,因此您可能必须构建您的序列化程序以符合其中一个,或者推出您自己的 Django REST 实现。
最后,无论您选择什么设计,完整记录 API 通常是一个好主意。无论 API 是基于 Web 还是使用某种本地编程语言,这都是正确的。 Web API 提供的关注点分离的部分吸引力在于,第 3 方可以消耗资源来构建您没有考虑过的应用程序或管道,更不用说在可维护性方面为您的项目代码库的未来更改带来的优势.有几个有趣的项目mentioned on the DRF site 可以帮助记录 API。 Swagger 是一个特别棒的工具,由提供旧版 Django REST Framework Docs 包的同一开发人员开发。
【讨论】:
太棒了。我将与我的同事讨论这个问题,我们将看看使用什么。非常感谢。以上是关于在 REST-ful api 中序列化外键字段的最佳实践是啥的主要内容,如果未能解决你的问题,请参考以下文章
Rails 3:在 Rails 中使用 JSON 响应 REST-ful 操作的正确方法是啥?
我可以禁用 Rest Framework API 浏览视图中的字段吗