如何避免在具有深度链接的RESTful客户端/服务器web应用程序中硬编码URL?

如何避免在具有深度链接的RESTful客户端/服务器web应用程序中硬编码URL?,rest,single-page-application,deep-linking,restful-url,api-design,Rest,Single Page Application,Deep Linking,Restful Url,Api Design,我正在开发一个SPA,它是RESTful web服务的客户端。客户端和服务器都是同一个项目的一部分,即我可以自由修改双方的代码。我一直在阅读RESTfulAPI设计,以确保我以“正确”的方式做每件事。我从阅读中学到的一点是,RESTful服务应该发布超链接,以便客户端可以访问更多信息,并且客户端除了入口点之外不应该有关于服务URL的硬编码信息。使用超链接可以使客户端在服务器更改URL时更加灵活 然而,当允许用户链接到特定的客户机状态时,我无法理解这种体系结构应该如何工作。例如: 其中一个视图是可

我正在开发一个SPA,它是RESTful web服务的客户端。客户端和服务器都是同一个项目的一部分,即我可以自由修改双方的代码。我一直在阅读RESTfulAPI设计,以确保我以“正确”的方式做每件事。我从阅读中学到的一点是,RESTful服务应该发布超链接,以便客户端可以访问更多信息,并且客户端除了入口点之外不应该有关于服务URL的硬编码信息。使用超链接可以使客户端在服务器更改URL时更加灵活

然而,当允许用户链接到特定的客户机状态时,我无法理解这种体系结构应该如何工作。例如:

其中一个视图是可供购买的书籍列表。客户端将浏览器的位置设置为
/books/
以标识此页面,后端数据来自从发布该URL的api入口点检索的端点
/api/books/
。服务URL使用如下JSON文档进行响应:

[
    {"title": "The Great Gatsby",
     "id": 24,
     "url": "http://localhost/api/books/24/"},

    < and so on >

]
[
{“标题”:“伟大的盖茨比”,
“id”:24,
“url”:”http://localhost/api/books/24/"},
<等等>
]
客户端使用它来生成可读的链接,当单击时,这些链接将转到单个书籍的详细视图。浏览器的位置更新为
/books/The great gatsby/24/
,因此用户可以将此视图添加书签并链接到它

当用户直接单击此链接时,客户端如何处理??在没有硬编码URL的情况下,它如何知道从何处获取这本书的信息

我所能想到的最好的请求顺序如下:

  • GET/api/
    -查看可用的服务(查找所有书籍)
  • OPTIONS/api/books/
    -查看书本上可用操作的描述(例如,它可以确保可以通过ID查找书本)
  • GET/api/books/?id=24
    -查看是否可以在浏览器位置找到id与之匹配的书籍
  • GET/api/books/24/
    -实际检索数据
  • 任何更短的内容都意味着客户机对API的URL有硬编码的了解。然而,从web应用程序的角度来看,这似乎效率极低


    我错过了什么把戏吗?有没有一种方法可以让客户端“知道”如何在不硬编码
    /api/books/24/
    端点的情况下获得关于book ID 24的更多详细信息?

    如果您从服务器请求此资源
    /books/the great gatsby/24/
    ,服务器应该使用特定于该URL的内容进行响应。目前,您可能正在分析
    window.location
    ,这有点像黑客

    如果
    /books/the great gatsby/24/
    是静态内容,那么您几乎没有选择:您将客户机的当前状态显式存储在某个位置(即
    /books?data=api/books/24
    或隐式
    /books/the great gatsby/24/
    ,这样客户机就必须知道如何将其转换为api资源

    RESTful方法是使用超文本来指示任何相关资源(即要呈现的数据)的位置,这使得标记成为一个合适的选择

    i、 e.抛弃静态内容,用

    但是,如果您始终保持对客户端的控制,并且不打算将API发布给第三方,那么放弃RESTful而直接使用RESTish可能会更有效率。

    另一个想法:

    您已经做出了以下假设,一个带有路径组件的url应该以某种方式映射到一个带有路径的url,如
    /api/books/24/

    为什么不添加一个小型服务服务器端来为您进行此映射?例如:

    /lookup?url=/books/the-great-gatsby/24/
    
    如果您担心额外的请求,该端点可以只返回实际的响应。它仍然可以有一个指向真实url的
    self
    链接(如果您愿意,也可以是canonical)


    或者,它可以直接重定向,并使用HTTP/2立即推送真正的资源。

    如果您让用户为URL添加书签,那么您需要在您的服务器上支持该位置。我不会将其称为“硬编码”信息。也许我不理解您的体系结构:如果有客户端代码生成URL,则由客户端决定重新生成内容。因此您想知道在哪里存储
    http://localhost/api/books/24/
    在这种情况下?@JochenBedersdorfer确切地说-我在Javascript代码中找不到替代URL生成器硬编码的方法,因此我可以高效地呈现
    /books/the great gatsby/24/
    视图。如果服务器在起初,没有什么可以阻止它添加
    http://localhost/api/books/24/
    作为
    链接
    标签的
    头部
    服务器不呈现任何页面,只为JS应用服务。即使呈现了,这样的链接标签仍然会将客户端和服务器耦合在一起(只有服务器知道如何解析客户端位置)