网站是否也应该是一种网络资源?

2023-12-23

每个网络应用程序 - 每个网站 - 都是一项服务。 (...) 使网站易于网络冲浪者使用的功能也使 Web 服务 API 易于程序员使用。

Richardson 和 Ruby,“RESTFul Web 服务”

正如我所希望的那样,同时也是 Web 服务的网站提供其资源的多种表示形式,具体取决于用户代理的请求。可以说,API 就是网站本身,不单独提供。

对于许多流行的“REST API”来说,情况并非如此。例如,Twitter 的 API 位于http://api.twitter.com/1/ http://api.twitter.com/1/,URI 中的“1”是 API 本身的版本。 Socialcast 还提供了 REST API,位于https://demo.socialcast.com/api/ https://demo.socialcast.com/api/,第三级名称是其寻址的网络的名称。

这对我来说似乎是错误的。如果我的博客位于http://www.example.com/blog http://www.example.com/blog,我不需要在不同的位置提供 API,只为机器人提供 JSON。而不是有http://www.example.com/blog/posts/ http://www.example.com/blog/posts/ and http://api.example.com/blog/posts http://api.example.com/blog/posts,两个不同的 URI,我应该只有前者,并且有多种可用的表示形式,其中application/json对于我希望提供给我的用户的 JSON API。

实施例1:浏览器询问我博客上的帖子;

Request:

curl -i \
 -H "Accept: text/html" \
 -X GET \
 http://www.example.org/blog/posts/

回复:

 200 OK
 Content-Type: text/html; charset=utf-8

 <html><body><h1>Posts</h1><ol><li><h2>My first post ...

实施例2:相同的 URI,但这次是机器人发出请求;

Request:

curl -i \
 -H "Accept: application/json" \
 -X GET \
 http://www.example.org/blog/posts/

回复:

 200 OK
 Content-Type: text/html; charset=utf-8

 {
    "posts": [
        {
            "id": 1,
            "title": "My first post" ...

API 的版本号应编码在请求标头的“Accept”字段中,最重要的是避免像 Twitter 那样强类型化 URI(“statuses/show.json?id=210462857140252672”或“statuses/show/210462857140252672.json” ”)。

采用统一方法可能会失去一些灵活性(但是,不应该很酷的 URI 永远不会改变? http://www.w3.org/Provider/Style/URI.html),但我认为坚持 REST(或者至少是我对它的解释)会带来更多好处。

哪种方法更正确:将 API 和网站分开,还是将它们统一?


这里没有对错之分。当您的 API 开发是由特定的客户需求驱动时,过于严格地遵循 REST 和 RFC 可能会很困难。

实际上,与 API 客户端相比,人类用户具有不同的行为模式,因此需要不同的处理。最明显的区别来自于这样一个事实:许多 API 都是数据密集型的,专为批量操作和数据转储而设计,而面向人类用户的应用程序则更具“反应性”,并且通常按步骤、按请求执行操作。因此,在许多项目中,API 的 URL 设计是优化以避免在多次网络往返和重复存储调用上浪费客户端和服务器资源。

在底层,API 实现通常具有与核心应用程序不同的设计,并针对 API 提供的操作类型进行了优化。例如,API 实现可能使用单独的缓存策略。现在,如果您将代码拆分出来,您可能需要创建一个仅处理 API 调用的主机集群。这就是将 API 放在另一个域上变得有利的地方负载管理:单独的域可以在高负载站点上实现更简单的负载平衡。相比之下,当您在同一域名上使用 /api URL 前缀(但具有单独的集群)时,您需要一个智能(L7 感知)负载均衡器来完成 API 和 Web 前端集群之间的请求流拆分工作,但这样的负载均衡器比较昂贵。

因此,Twitter 之类的公司将 API 分开可能有很好的技术原因,但对其他实现的引用可能不适用于您的项目。如果您处于设计的早期阶段,您可能希望从同一域上的统一 URL 方案开始,但最终您可能会发现有一些好的现实用例可以让您改变方法,然后...重构。

附:这里有关于版本控制的冗长讨论 -API 版本控制的最佳实践? https://stackoverflow.com/questions/389169/best-practices-for-api-versioning

附言我发现强类型 URL 有助于快速调试。您只需将 .json 格式的 URL 输入浏览器即可快速获取结果,而无需切换到命令行。但同意你的观点,“接受”标头是首选方法

P.S.S.S。 API 的 SEO?我可以看到良好的 URL 设计是如何有益的,但对于搜索引擎来说,如果您的服务在同一路径/域名上提供多种输出格式,那么它可能无关紧要。归根结底,搜索引擎是为人类用户构建的,而人类用户不会使用 XML 和 JSON。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

网站是否也应该是一种网络资源? 的相关文章

  • 在应用程序中注册API

    通过 django rest framework 我正在使用DefaultRouter 我想为多个应用程序提供 API 所以我的问题是我能否以 django 方式执行此操作 并将我的路由器注册放入每个应用程序 URLconf 中 并让它们显
  • 找不到可接受的代表

    我是 Spring Boot 的新手 我可能会犯一些愚蠢的错误 所以提前对此类问题表示歉意 我正在尝试编写接受以下 JSON 的 POST API id null a 1 3 b somestring mapJson monday 10 0
  • 如何在没有可用行选择器的情况下为 APEX 21.1 REST 数据源设置数据配置文件

    我正在使用 APEX 21 1 并为 Web 服务创建了一个 REST 数据源 该服务以以下格式返回响应 1499040000000 A time stamp 0 01634790 A value etc 1499040000100 A t
  • HTTP请求压缩

    一般用例 想象一下一个正在上传大量 JSON 的客户端 内容类型应保留application json因为这描述了实际数据 Accept Encoding 和 Transfer Encoding 似乎是为了告诉服务器应该如何格式化响应 看起
  • 是否应该在 REST API PUT 请求中传递资源及其相关资源的所有字段?

    假设我有一个票证和评论资源 门票可以有很多评论 在您的更新端点中HTTP PUT api tickets
  • 您可以从 AuthorizeAttribute 返回 HTTP 响应而不引发异常吗?

    我在各种控制器上使用 AuthorizeAttribute 可能需要根据请求本身的某些属性返回 403 或 429 请求过多 我完全在自定义 OnAuthorization 实现中实现了它 然后在必要时抛出一个带有适当响应代码的新 Http
  • 如何使用独立的 Jetty 进行服务器推送

    我正在尝试使用独立的 Jetty 在静态网站上测试服务器推送功能 我的网站由一个index html 1个CSS 一堆图像组成 目录结构为 Album index html style css images image 1 png a se
  • 如何在不同的端口上运行@RestController?

    我在用着spring rest创造一些 RestController小服务程序 该应用程序不是在网络服务器上运行 而是作为带有嵌入式 tomcat 的简单命令行工具运行 它们中的大多数应该在公共端口上运行 该端口是使用指定的server p
  • HttpRequest PUT内容到poco库中

    我想使用 HTTP PUT 请求将一些数据从 C 应用程序发送到服务器 我在用poco http pocoproject org我的应用程序中的网络库 我正在使用这个代码片段 HTTPClientSession session uri ge
  • PHP:在 CURL GET 调用中使用 API 密钥

    我看过关于使用 api 密钥在curl 中验证 post 调用的帖子 我有一个 GET 调用 需要 apikey 进行授权 即请求必须具有包含 apiKey 的授权标头 我已经获得了 api 密钥并尝试将其用于 GET 调用
  • RESTful API:仅用于验证的方法/标头组合

    我希望我的 API 有一个仅验证请求 例如 如果我有一个 URL 例如 http api somesite com users 12345 用户正在客户端上填写一份信息表单 我最终会将其修补 放置 发布到该资源 当用户填写表单时 我可能希望
  • 如何在Delphi中下载一个非常简单的HTTPS页面?

    我尝试了在这里看到的代码 但它不适用于 HTTPS 我需要将此页面作为字符串下载 并在其上添加一些换行符 以便将信息按顺序放入 TMemo 中 怎么做 我尝试使用 Indy 但由于 SSL 问题而失败 我尝试了此页面的解决方案 如何将网页下
  • 在处理程序之后访问 HTTP 请求上下文

    在我的日志记录中间件 链中的第一个 中 我需要访问一些在链下游的某些身份验证中间件中编写的上下文 并且仅在处理程序本身执行之后 旁注 需要首先调用日志记录中间件 因为我需要记录请求的持续时间 包括在中间件中花费的时间 此外 当权限不足时 身
  • 以 RESTful 方式增加资源计数器:PUT 与 POST

    我有一个带有计数器的资源 为了举例 我们将该资源称为profile 计数器是数量views对于该配置文件 Per the 休息维基 http rest blueoxen net cgi bin wiki pl HttpMethods PUT
  • 返回重定向作为对 Ajax(fetch、XHR 等)请求的响应

    如果浏览器收到对 ajax 请求的重定向响应 会发生什么 如果浏览器收到对 ajax 请求的重定向响应 会发生什么 如果服务器发送重定向 又名 302 响应加上 Location 标头 浏览器将自动遵循重定向 对此的回应second请求 假
  • iPhone 应用程序中的异步、同步、线程

    我正处于一个应用程序的设计阶段 该应用程序将利用 REST Web 服务 并且在使用异步 同步和线程方面遇到了困境 这是场景 假设您有三个选项可供深入研究 每个选项都有自己的基于 REST 的资源 我可以使用同步请求延迟加载每个请求 但这会
  • Django 响应总是用 text/html 分块无法设置内容长度

    在我的Django应用程序的views py中 我在尝试设置以下HTTP标头字段后返回一个HttpResponse对象 Create a Response Object with the content to return response
  • 当会话令牌无效时,我应该使用什么状态代码?

    创建 Web 服务 RESTful 时 当会话令牌无效时我应该使用什么状态代码 目前我公司的人给我发了一个404 未找到 但我认为这是不正确的 因为资源存在 也许我应该使用 401 Unauthorized 你怎么认为 您建议我在这种情况下
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 有没有办法使用 ASP.NET 在用户离开页面时始终运行某些服务器端代码?

    我想知道当用户离开 ASP NET 中的页面时是否有任何方法可以始终运行一些服务器端代码 页面卸载事件不好 因为如果有人单击链接 则不会调用该事件 理想情况下 即使用户关闭浏览器 我也希望代码能够运行 我怀疑我所问的问题是不可能的 但问一下

随机推荐