我认为我对REST的大量了解显然是错误的 - 而且我并不孤单.这个问题有很长的引导时间,但似乎是必要的,因为信息有点分散.如果你已经熟悉这个话题,最后会出现实际问题.
从Roy Fielding的第一段开始,REST API必须是超文本驱动的,很明显他认为他的工作被广泛误解:
我对使用REST API调用任何基于HTTP的接口的人数感到沮丧.今天的例子是SocialSite REST API.那就是RPC.它尖叫RPC.显示器上有很多耦合,它应该被赋予X等级.
Fielding继续列出REST API的几个属性.他们中的一些人似乎反对SO和其他论坛的常见做法和共同建议.例如:
应输入REST API,除了初始URI(书签)和适用于目标受众的标准化媒体类型集之外没有任何先验知识(即,任何可能使用API的客户都应该理解)....
REST API不能定义固定资源名称或层次结构(客户端和服务器的明显耦合)....
REST API应该花费几乎所有的描述性工作来定义用于表示资源和驱动应用程序状态的媒体类型,或者为现有标准媒体类型定义扩展关系名称和/或启用超文本的标记....
"超文本"的概念起着核心作用 - 远比URI结构或HTTP动词的含义更重要.其中一条评论中定义了"超文本":
当我[菲尔丁]说超文本时,我指的是信息和控制的同时呈现,使得信息成为用户(或自动机)获得选择和选择动作的可供性.超媒体只是对文本意味着在媒体流中包含时间锚点的扩展; 大多数研究人员都放弃了这一区
超文本不需要是浏览器上的HTML.机器在理解数据格式和关系类型时可以跟踪链接.
我猜这一点,但上面的前两点似乎表明,Foo资源的API文档看起来像下面这样导致客户端和服务器之间的紧密耦合,并且在RESTful系统中没有位置.
GET /foos/{id} # read a Foo POST /foos/{id} # create a Foo PUT /foos/{id} # update a Foo
相反,应该强制代理发现所有Foos的URI,例如,针对/ foos发出GET请求.(那些URI可能会遵循上面的模式,但这不是重点.)响应使用的媒体类型能够传达如何访问每个项目以及可以用它做什么,从而产生上述第三点.因此,API文档应侧重于解释如何解释响应中包含的超文本.
此外,每次请求到Foo资源的URI时,响应都包含代理发现如何继续所需的所有信息,例如,通过其URI访问关联资源和父资源,或者在创建后采取措施/删除资源.
整个系统的关键在于响应由媒体类型中包含的超文本组成,该超文本本身传达给代理选项以进行处理.它与浏览器为人类工作的方式没有什么不同.
但这只是我在这个特殊时刻的最佳猜测.
菲尔丁发布了一个后续行动,他回应批评说他的讨论过于抽象,缺乏例子和行话丰富:
其他人会试图以更直接或适用于当今某些实际问题的方式破译我所写的内容.我可能不会,因为我太忙于处理下一个话题,准备会议,写另一个标准,到一些遥远的地方旅行,或者只是做一些让我觉得自己赚到了薪水的小事.
那么,REST专家的两个简单问题就是有一个实际的思维方式:你如何解释菲尔丁在说什么,以及在记录/实现REST API时如何将其付诸实践?
编辑:这个问题是一个例子,说明如果你没有关于你所谈论的内容的名称,学习一些东西是多么困难.在这种情况下,名称是"超媒体作为应用程序状态的引擎"(HATEOAS).
我认为你的解释主要涵盖它.URI是不透明的标识符,在大多数情况下,它们不应该超出用户代理用来访问应用程序的书签URI.
至于记录,这个问题已经完成了很多次.您可以记录媒体类型及其包含的超链接控件(链接和表单),以及您希望的交互模型(请参阅AtomPub).
如果您记录URI或如何构建它们,那么您做错了.
你的解释对我来说似乎是对的.我确实相信Fielding的约束可以实际应用.
我真的希望看到有人发布一些如何记录REST接口的好例子.有这么多糟糕的例子,有一些有效的例子指向用户将是非常有价值的.
我一直在寻找一个在HATEOAS之后编写的API的一个很好的例子,但是找不到它(我发现SunCloud API和AtomPub的东西很难应用于"正常"的API情况).所以我尝试在我的博客上做一个真实的例子,跟随Roy Fieldings关于成为一个合适的REST实现意味着什么的建议.我发现很难提出这个例子,尽管它原则上相当简单(只是在使用API而不是网页时会感到困惑).我得到了Roy提出的问题并同意,这只是为了正确实现API的思维方式的转变.
看看:使用Rest的API示例