GET
HTML(用户友好)版本的东西,那么流行的答案是通过HTTP头字段使用内容否定。最终目标似乎只有遵循REST范例的URI。
但是,显示无法映射到实体但仍然需要的网页的“正确”方法是什么?
也许我举一个例子来澄清我的意思。假设我们有一个集合Persons
和一个实体Person
。
然后我们
POST /Persons/
在集合中创建新人DELETE /Person/{id}/
删除此人PUT /Person/{id}/
修改此人(是的,我知道它也可能意味着创建一个人)GET /Persons/
获取所有人员名单GET /Person/{id}/
获取个人关于GET
操作,我通常会发现建议使用请求的Accept
和X-Requested-With
头字段来创建一个返回“裸”人对象的响应在计算机可读的表示(即JSON,XML等)或返回浏览器的完整网页。
但是PUT
操作是什么。最终,此操作将发送将要创建的裸人对象(即JSON,XLM),但在此步骤之前,我需要从用户收集数据。这意味着我需要一些空的网络表单,这对于人类用户来说只是“眼睛糖果”。当然,我可以像GET /newPersonForm/
那样,但似乎这与REST哲学相矛盾,因为/newPersonForm/
是一个只指向某个用户界面元素的URI。
目前我看到了选项:
对两种URI使用相同的名称空间:
POST /Persons/
- > REST api DELETE /Person/{id}/
- > REST api PUT /Persons/{id}/
- > REST api GET /Persons/
- > REST api或UI(内容否定后)GET /Person/{id}/
- > REST api或UI(内容否定后)GET /Person/creationForm
- >非REST,纯UI GET /aboutus
- >非REST,纯用户界面,其他公司信息创建单独的名称空间:
/api/...
- >包含REST的所有内容/ui/...
- >包含html网页采用第一种方法,我觉得它有些“不干净”。虽然第二种方法看起来更清洁,但我看到两个问题。首先,如果一个人干净地遵循这种方法,就会得到很多双重URI,因为一个人不会忘记内容,并且每个REST函数都有一个UI网页。我有GET /api/Person/{id}/
返回JSON对象,GET /ui/Person/{id}
返回浏览器版本。其次,我觉得这种方法与REST哲学相矛盾,因为搜索egines和web crawler无法理解网站的结构。
任何建议最佳做法是什么?
答案 0 :(得分:1)
首先,让我们先解决一些误解。
您可以通过URI识别语义的任何内容都是资源。
HTTP方法不会映射到这样的CRUD操作。有关详情,请阅读this答案。我建议你在继续阅读这个答案之前阅读它。 This one也可能会有所帮助。
在REST范例之后没有 URI这样的东西。 REST对URI施加的唯一约束是它们必须识别一个且仅一个资源,并且它们必须被视为原子标识符。 URI的语义是无关紧要的,尽管显然你应该设计对开发人员和用户有意义的URI。
正如您已经想到的那样,返回用户友好的表示形式的正确方法是通过Accept
标题进行协商。如果它不是映射到数据库的东西并不重要。这只是服务器知道的实现细节,而这正是REST的意义所在。当您从REST API检索某些内容时,无论是来自应用程序服务器,来自某个地方的缓存,来自Amazon S3提供的静态文件,还是来自FTP链接,都无关紧要。客户应该只关注链接,例如当您点击网页上的链接而不关心结果来自哪里时。
您提供的两个选项都是有效的,但这与REST无关。在api
和ui
中分隔它们是一种很好的方式来组织事物,但对REST来说真正重要的是客户端如何获取这些链接。如果他们通过阅读文档中的URI并填充值来实现客户端,那就不是REST。
从网页浏览的角度考虑一下。你如何到达/newPersonForm
html页面?你在其他地方跟着一个带有标签的链接,告诉你点击它来创建一个新人。如果您只需点击一次,则无论是/newPersonForm
还是/forms/newperson
还是/persons
都无关紧要。 REST以完全相同的方式工作。