我想用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等一些众所周知的客户端库添加哪种方式。
答案 0 :(得分:5)
您似乎正在使用自我描述和可探索的Web API服务,这实际上是原始REST概念的核心功能,称为Hypermedia as the Engine of Application State (HATEOAS)。从本质上讲,符合HATEOAS标准的Web服务不依赖于除初始URL入口点之外的系统资源的任何先验知识。
这与Service Oriented Architecture (SOA)形成鲜明对比,在http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas中,各个服务基本上没有关联,并且需要事先知道它们的存在,将多个服务调用串联在一起,以便用多个可能相关的资源完成一些任务。
对REST API的大多数引用实际上并不完全是REST,并且应该更准确地描述为Web API,因为它们更符合SOA设计:一组特定实例的URL和一组实例的集合。一种特殊的类型。这还包括使用不同的HTTP谓词(GET,PATCH,POST,PUT)来执行对这些资源执行的各种操作。 Django REST框架(DRF)实际上有一个关于这个主题的页面,其中包含有关真正RESTful设计的一些重要资源的链接,包括Roy Fielding的论文:
Hypertext Application Language (HAL)
我推测当前使用术语“REST API”涉及许多开发人员的启示,即实现真正的RESTful服务远非微不足道,并且在许多情况下会针对特定用例进行过度设计。也许这是“作为善的敌人的完美”的一个很好的例子。对于使用AngularJS作为客户端框架通过DRF与Django后端进行交互的情况,尤其如此。 AngularJS框架中没有任何内容可以解析真正的RESTful设计,以自动为给定资源提供各种应用程序状态。此外,相同的开发人员通常负责JavaScript和Python代码,因此缺乏自描述API并不是开发的主要障碍。
关于在JSON中实现真正的RESTful API,有几个项目试图促进这一点,即JSON Linked Data (JSON-LD)和mentioned on the DRF site。但是,我不知道DRF本身支持这些中的任何一个,因此您可能必须构建序列化程序以符合其中一个,或者滚动您自己的Django REST实现。
最后,无论您选择何种设计,完全记录API通常都是个好主意。无论API是基于Web还是使用某种本机编程语言,都是如此。 Web API提供的关注点分离的部分吸引力在于,第三方可以消耗资源来构建您未考虑过的应用程序或管道,更不用说为将来更改项目代码库的可维护性带来的优势。有一些有趣的项目Swagger可以帮助记录API。 {{3}}是一个特别棒的,由提供较旧的Django REST Framework Docs包的同一个开发人员开发。