Json RESTAPI和UI网页URI模式的最佳实践

Json RESTAPI和UI网页URI模式的最佳实践,json,api,rest,user-interface,Json,Api,Rest,User Interface,在多年没有从事web编程之后,我现在开始从头开始编写一个新的web应用程序。我学习了REST的诀窍,并找到了一些关于好的和坏的“URI样式”的helfful演示和网络研讨会。但所有这些教程似乎都假设只有资源可以映射到数据库中持久存在的实体。如果需要获取某个内容的HTML(用户友好)版本,那么普遍的答案是通过HTTP头字段使用内容协商。最终目标似乎只有遵循REST范式的URI 但是,显示无法映射到实体但仍需要的网页的“正确”方式是什么 也许我举个例子来澄清我的意思。假设我们有一个集合Persons

在多年没有从事web编程之后,我现在开始从头开始编写一个新的web应用程序。我学习了REST的诀窍,并找到了一些关于好的和坏的“URI样式”的helfful演示和网络研讨会。但所有这些教程似乎都假设只有资源可以映射到数据库中持久存在的实体。如果需要
获取某个内容的HTML(用户友好)版本,那么普遍的答案是通过HTTP头字段使用内容协商。最终目标似乎只有遵循REST范式的URI

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

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

那么我们有

  • POST/Persons/
    在收藏中创建新人物
  • DELETE/Person/{id}/
    删除此人
  • PUT/Person/{id}/
    修改此人(是的,我知道这也意味着创建一个)
  • GET/Persons/
    获取所有人员的列表
  • GET/Person/{id}/
    获取个人
  • 等等
关于
GET
操作,我通常会建议使用请求的
Accept
X-Requested-With
头字段来创建一个响应,该响应在计算机可读的响应中返回“裸”person对象(即JSON、XML等)或者为浏览器返回完全成熟的网页

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

目前,我看到了以下几种选择:

  • 对两种URI使用相同的名称空间:

    • POST/Persons/
      -->RESTAPI
    • DELETE/Person/{id}/
      -->RESTAPI
    • PUT/Persons/{id}/
      -->RESTAPI
    • GET/Persons/
      -->REST api或UI(内容协商后)
    • GET/Person/{id}/
      -->REST api或UI(内容协商后)
    • GET/Person/creationForm
      -->非REST,纯UI
    • GET/aboutus
      -->非REST、纯UI、附加公司信息
  • 使用单独的名称空间:

    • /api/…
      -->包含REST的所有内容
    • /ui/…
      -->包含html网页
  • 对于第一种方法,我觉得有点“不干净”。虽然第二种方法看起来更干净,但我看到两个问题。首先,如果一个人干净地遵循这种方法,就会得到更多的双URI,因为他不需要内容协商,并且每个REST函数都有一个UI网页。我有
    GET/api/Person/{id}/
    返回JSON对象,有
    GET/ui/Person/{id}
    返回浏览器版本。其次,我觉得这种方法与REST哲学相矛盾,因为搜索引擎和网络爬虫无法理解网站的结构


    有什么建议是最佳实践吗?

    首先,让我们排除一些误解

  • 任何具有URI可识别语义的内容都是资源

  • HTTP方法不会像那样映射到CRUD操作。阅读答案,了解更多信息。我建议你在继续阅读这个答案之前先阅读它。可能也会有帮助

  • 没有遵循REST范式的URI。REST对URI施加的唯一约束是它们必须标识一个且仅标识一个资源,并且必须将它们视为原子标识符。URI的语义是不相关的,尽管显然您应该设计对开发人员和用户有意义的URI

  • 正如您已经了解到的,返回用户友好的内容表示的正确方法是通过
    Accept
    标题进行协商。不管它是否映射到数据库。这是一个只有服务器知道的实现细节,这就是REST的内容。当您从RESTAPI检索某些内容时,它是否来自应用程序服务器、某个缓存、AmazonS3提供的静态文件,甚至是FTP链接都无关紧要。客户端应该只关注链接,比如当你点击网页上的链接时,你不在乎结果来自哪里

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


    从网络浏览的角度考虑一下。如何到达
    /newPersonForm
    html页面?你在其他地方找到了一个链接,上面有一个标签告诉你点击它来创建一个新的人。如果你是点击者,那么无论是
    /newPersonForm
    还是
    /forms/newperson
    还是简单的
    /persons
    ,都没有关系。REST的工作方式完全相同。

    我阅读了这两个链接。但我没有发现我在哪里使用了错误的HTTP方法到CRUD操作的映射。对我来说唯一的新信息是PUSH可以用作任何东西的“回退”方法,因为它没有预先确定的标准化语义