REST api和UI网页的URI模式的最佳实践

时间:2014-10-30 10:04:53

标签: json api rest user-interface

经过多年的网络编程后,我现在开始从头开始编写一个新的Web应用程序。我学习了REST的绳索,并发现了一些关于好的和坏的“URI样式”的helfful演示和网络研讨会。但是所有这些教程似乎都假设只有资源可以映射到数据库中持久存在的权限。如果需要GET HTML(用户友好)版本的东西,那么流行的答案是通过HTTP头字段使用内容否定。最终目标似乎只有遵循REST范例的URI。

但是,显示无法映射到实体但仍然需要的网页的“正确”方法是什么?

也许我举一个例子来澄清我的意思。假设我们有一个集合Persons和一个实体Person

然后我们

  • POST /Persons/在集合中创建新人
  • DELETE /Person/{id}/删除此人
  • PUT /Person/{id}/修改此人(是的,我知道它也可能意味着创建一个人)
  • GET /Persons/获取所有人员名单
  • GET /Person/{id}/获取个人

关于GET操作,我通常会发现建议使用请求的AcceptX-Requested-With头字段来创建一个返回“裸”人对象的响应在计算机可读的表示(即JSON,XML等)或返回浏览器的完整网页。

但是PUT操作是什么。最终,此操作将发送将要创建的裸人对象(即JSON,XLM),但在此步骤之前,我需要从用户收集数据。这意味着我需要一些空的网络表单,这对于人类用户来说只是“眼睛糖果”。当然,我可以像GET /newPersonForm/那样,但似乎这与REST哲学相矛盾,因为/newPersonForm/是一个只指向某个用户界面元素的URI。

目前我看到了选项:

  1. 对两种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,纯用户界面,其他公司信息
  2. 创建单独的名称空间:

    • /api/... - >包含REST的所有内容
    • /ui/... - >包含html网页
  3. 采用第一种方法,我觉得它有些“不干净”。虽然第二种方法看起来更清洁,但我看到两个问题。首先,如果一个人干净地遵循这种方法,就会得到很多双重URI,因为一个人不会忘记内容,并且每个REST函数都有一个UI网页。我有GET /api/Person/{id}/返回JSON对象,GET /ui/Person/{id}返回浏览器版本。其次,我觉得这种方法与REST哲学相矛盾,因为搜索egines和web crawler无法理解网站的结构。

    任何建议最佳做法是什么?

1 个答案:

答案 0 :(得分:1)

首先,让我们先解决一些误解。

  1. 您可以通过URI识别语义的任何内容都是资源。

  2. HTTP方法不会映射到这样的CRUD操作。有关详情,请阅读this答案。我建议你在继续阅读这个答案之前阅读它。 This one也可能会有所帮助。

  3. 在REST范例之后没有 URI这样的东西。 REST对URI施加的唯一约束是它们必须识别一个且仅一个资源,并且它们必须被视为原子标识符。 URI的语义是无关紧要的,尽管显然你应该设计对开发人员和用户有意义的URI。

  4. 正如您已经想到的那样,返回用户友好的表示形式的正确方法是通过Accept标题进行协商。如果它不是映射到数据库的东西并不重要。这只是服务器知道的实现细节,而这正是REST的意义所在。当您从REST API检索某些内容时,无论是来自应用程序服务器,来自某个地方的缓存,来自Amazon S3提供的静态文件,还是来自FTP链接,都无关紧要。客户应该只关注链接,例如当您点击网页上的链接而不关心结果来自哪里时。

    您提供的两个选项都是有效的,但这与REST无关。在apiui中分隔它们是一种很好的方式来组织事物,但对REST来说真正重要的是客户端如何获取这些链接。如果他们通过阅读文档中的URI并填充值来实现客户端,那就不是REST。

    从网页浏览的角度考虑一下。你如何到达/newPersonForm html页面?你在其他地方跟着一个带有标签的链接,告诉你点击它来创建一个新人。如果您只需点击一次,则无论是/newPersonForm还是/forms/newperson还是/persons都无关紧要。 REST以完全相同的方式工作。