自我描述的 RESTful api

Selfdescribing RESTful api

本文关键字:api RESTful 描述 自我      更新时间:2023-09-26

我正在构建一个(RESTful(api(使用HTTP(,我想与javascript一起使用。

我发现我在javascript中自己写的东西,比如

function getPost(id)
{
    $.getJSON("/api/post/" + id, function(data){
        // Success!
    });
}

一定有一种比在javascript中硬编码api更聪明的方法,也许就像查询api本身的getPost网址应该是什么样子一样?

function getApiPostUrl()
{
    $.getJSON("/api/getpost/");
}

返回类似的东西

url: "/api/post/:id"

javascript可以解析它,以获取实际获取id=:id帖子的url。我喜欢这种方法。

这是这样做的标准方法吗?我正在寻找一种好的方法,这样我就不必发明这一切,如果已经存在一个好的解决方案。

好吧,根据定义,RESTful API 应包含完整的 URI - 资源标识符,而不仅仅是资源的路径。因此,您的问题更多的是关于您如何设计整个 API 的问题。

因此,例如,您的 API 可能包含一个包含您网站内所有帖子列表的http://fqdn/api/posts,例如:

[ "http://fqdn/api/posts/1",
  "http://fqdn/api/posts/2",
  "http://fqdn/api/posts/3" ]

然后你的 JavaScript 只遍历列表中的值,永远不需要为每个资源创建路径。您只需要有一个已知的入口点。这是HATEOAS概念,它使用超链接作为 API 来标识应用程序的状态。

总而言之,最好彻底考虑您的应用程序(您可以使用状态机或序列图等UML工具(,以便您可以使用一组简单而有效的序列来定义您的API。然后,对于每个序列,最好有一个第一个状态,你可以有一个第一个步骤链接到所有序列。

  • 资源:
    • ACM 文章
    • Restful API Design 第二版幻灯片
    • 宁静的 API 设计博客

是的,有很多标准方法可以做到这一点。您要寻找的是"超媒体 API"——即具有嵌入式超媒体元素的 API,例如像您这样的链接模板,还有纯链接和更高级的操作(API 表单(。

下面是使用 Mason 在响应中嵌入链接模板的示例表示形式:

{
  id: 1234,
  title: "This is issue no. 1",
  "@link-templates": {
    "is:issue-query": {
      "template": "http://issue-tracker.org/mason-demo/issues-query?text={text}&severity={severity}&project={pid}",
      "title": "Search for issues",
      "description": "This is a simple search that do not check attachments.",
      "parameters": [
        {
          "name": "text",
          "description": "Substring search for text in title and description"
        },
        {
          "name": "severity",
          "description": "Issue severity (exact value, 1..5)"
        },
        {
          "name": "pid",
          "description": "Project ID"
        }
      ]
    }
  }
}

URL 模板格式在 RFC 6570 中标准化。

Mason 并不是超媒体 API 唯一可用的媒体类型。还有HAL,Sirene,Collection-JSON和Hydra。

这里有一个关于超媒体好处的讨论。

您的代码明显违反了自描述性消息和超媒体作为 REST 统一接口约束的应用程序状态(缩写 HATEOAS(的引擎。

根据 HATEOAS 的说法,您应该发回超链接,客户端应该遵循它们,这样它就不会因 API 的更改而中断。超链接不等于 URL。它包含一个URL,一个HTTP方法,可能是正文的内容类型,可能是输入字段等......

根据自描述消息,您应该为数据、链接、输入字段等添加语义......客户端应该理解该语义并采取相应的行为。因此,例如,您可以将"创建发布"API特定的链接关系添加到超链接中,以便客户端了解它是用于创建帖子的。客户端应始终使用这些类型的语义,而不是分析 URL。

URL 始终是特定于 API 的,语义不一定,因此这些约束将客户端与 API 分离。之后,客户端不会因URL更改甚至数据结构更改而中断,因为它将使用标准的超媒体格式(例如HAL,JSON-LD,ATOM甚至HTML(和语义(可能是RDF(来解析响应正文。