REST API和UI网页的URI模式的最佳实践
经过多年的网络编程后,我现在开始从头开始编写新的Web应用程序。我学习了REST的一些技巧,并发现了一些有关好的和不好的“URI风格”的helfful演示和网络研讨会。但是,所有这些教程似乎都假设只有可以映射到数据库中存在的实体的资源。如果需要GET
一个HTML(用户友好)版本的东西,那么普遍的答案是通过HTTP头字段使用内容negiotation。最终目标似乎只有遵循REST范式的URI。REST API和UI网页的URI模式的最佳实践
但是,显示无法映射到实体但仍然需要的网页的“正确”方式是什么?
也许我举个例子来说明我的意思。假设我们有一个集合Persons
和实体Person
。
然后我们有
-
POST /Persons/
到集合 -
DELETE /Person/{id}/
删除的人 -
PUT /Person/{id}/
到modifiy的人(是的,我知道这也意味着创建一个在创建新的联系人) -
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(后内容negiotation) -
GET /Person/{id}/
- > REST API或UI(后内容negiotation) -
GET /Person/creationForm
- >非REST,纯UI -
GET /aboutus
- >非-REST,纯粹的UI,更多的公司信息
-
-
进行单独的命名空间:
-
/api/...
- >包含家居REST -
/ui/...
- >包含HTML网页
-
第一个方法我觉得这是somebit “不干净”。虽然第二种方法看起来更清洁,但我看到两个问题。首先,如果采用这种方法干净利落,可以获得更多的双重URI,因为不需要内容负担,并且每个REST功能都有一个UI网页。我有GET /api/Person/{id}/
返回一个JSON对象,GET /ui/Person/{id}
返回浏览器版本。其次,我觉得这种方法与REST哲学相矛盾,因为搜索范例和网络爬虫不能理解网站的结构。
任何建议最佳实践是什么?
首先,让我们看看一些误解。
任何你可以通过URI识别语义的东西都是一种资源。
HTTP方法不映射到这样的CRUD操作。阅读this回答更多。我建议你在继续阅读这个答案之前阅读它。 This one也可能会有帮助。
有没有这样的事情作为URI遵循REST范式。 REST对URI的唯一约束是它们必须标识一个且只有一个资源,并且它们必须被视为原子标识符。 URI的语义是无关紧要的,尽管显然你应该设计对开发者和用户有意义的URI。
正如你已经想通了,返回的东西一个用户友好的表示正确的做法是通过经Accept
头谈判。不要紧,如果它不是映射到数据库的东西。这是一个只有服务器知道的实现细节,这就是REST的内容。当您从REST API检索某些内容时,无论它是来自应用程序服务器,某处缓存还是来自Amazon S3提供的静态文件,甚至是FTP链接。客户端应该简单地遵循链接,比如当您点击网页上的链接时,您不关心结果来自何处。
你提出的两个选项都是有效的,但这与REST无关。在api
和ui
中分开它们是为你组织事情的一个很好的方式,但是REST真正重要的是客户端如何获得这些链接。如果他们通过阅读文档中的URI并填充值来实现客户端,那不是REST。
从网页浏览的角度思考它。你如何达到/newPersonForm
的html页面?你在别的地方跟着一个链接,上面有一个标签告诉你点击它来创建一个新的Person。如果你是一个点击,它不在于它是否/newPersonForm
或/forms/newperson
或简单地/persons
。 REST的工作方式完全相同。
我阅读了这两个链接。但是我没有找到我使用错误的HTTP方法映射到CRUD操作的地方。对我来说唯一的新信息是PUSH可以用作任何事情的“后备”方法,因为它没有预定义的标准化语义。无论如何,我决定去选项1,以避免过多的双重URI,并将使用“GET/person/new”来获得一个空的表单。它最好匹配“GET/person/{id}”,它返回相同的表单,但与用户数据。 – user2690527 2014-10-31 21:33:42