支持 JSON-Home 用于 API 可发现性¶
https://blueprints.launchpad.net/nova/+spec/nova-api-json-home
Nova 需要为客户端提供标准的 API 发现方式。本规范建议使用 JSON-Home 作为该方式。
问题描述¶
目前 Nova API 通过“list extensions” API 提供可用的 API 列表,但这种方式是 Nova 特有的,并非标准方式。此外,客户端仅从“list extensions”的结果中无法得知可用的 API 资源 URL,开发者需要研究 Nova 的实现,因为结果并未直接显示可用的 API 资源 URL。从整个 OpenStack 项目的角度来看,这些方式不一致,应用程序程序员需要编写应用程序来以不同的方式处理这些 API。
用例¶
最终用户可以通过一种通用的方式了解云服务上可用的 API 以及如何访问这些功能。例如,最终用户可以通过在 GET 请求的 accept header 中传递 ‘application/json-home’ 来获取可用的 REST URL(v2/{project-id}/servers 等)。开发者可以获取包含可用方法(GET/POST/PUT 等)细节的完整 REST URL 集合,并基于这些信息创建 API 文档。理想情况下,可以从该功能自动生成 API 文档。
项目优先级¶
无。
提议的变更¶
JSON-Home 是一个标准,Keystone 已经在 Keystone REST API 上实现了 JSON-Home [1]。本规范/蓝图建议为 Nova v2.1 API 支持 JSON-Home。
在 JSON-Home 规范 [2] 中,JSON-Home 仅在传递 ‘application/json-home’ 在 accept header 中时才有效。如果 nova-api 接收到它,nova-api 将以 JSON-Home 格式向客户端提供可用的 REST URL。例如,如果客户端使用 accept header ‘application/json-home’ 发送 “GET /v2.1”,nova-api 将提供以下数据
{
"resources": {
"https://docs.openstack.org/api/openstack-compute/2.1/rel/servers": {
"href-template": "/v2.1/{project_id}/servers",
"href-vars": {
"project_id": "https://docs.openstack.org/api/openstack-compute/2.1/param/project_id"
}
},
"https://docs.openstack.org/api/openstack-compute/2.1/rel/flavors": {
"href-template": "/v2.1/{project_id}/flavors",
"href-vars": {
"project_id": "https://docs.openstack.org/api/openstack-compute/2.1/param/project_id"
}
},
[..]
}
}
resources 属性的键是链接关系类型。需要为键选择一种关系类型。IANA 注册了多种关系类型,但没有指定用于计算 API 资源的类型。如果某个组不想在 IANA 注册关系(参见 RFC 5988 第 4.2 节“Extension Relation Types” [3]),他们可以使用一些唯一的 URL 代替。应用程序可能会获取此 URL 以获取有关关系的更多信息,因此我们应该选择一个可以潜在地用于提供有关关系信息并描述资源的 URL。Keystone 在 https://docs.openstack.org/api/openstack-identity/3/rel 上发布了它。此外,Nova 已经将其 XSD 文件发布在 https://docs.openstack.org/api/openstack-compute/2/xsd 上。因此,Nova 应该发布类似的位置以保持一致性。对于 v2.1 资源,关系类型链接将是 https://docs.openstack.org/api/openstack-compute/2.1/rel,如上述示例所示。在 v2.1 API + 微版本中,我们将继续使用相同的端点(/v2.1),并且可以对所有微版本使用相同的链接。
如果针对特定 URL 查询(例如 GET /v2.1/{project_id}/servers),客户端可以在“hints”属性上获取更多详细信息(可用的 HTTP 方法、格式),例如
{
"resources": {
"https://docs.openstack.org/api/openstack-compute/2.1/rel/servers": {
"href-template": "/v2.1/{project_id}/servers",
"href-vars": {
"project_id": "https://docs.openstack.org/api/openstack-compute/2.1/param/project_id"
},
"hints": {
"allow": ["GET", "POST", "PUT", "DELETE"],
"formats": {
"application/json": {}
},
"accept-post": ["application/json"],
"accept-put": ["application/json"]
}
}
}
}
“hints”属性还可以包含“status”,这对于不兼容的更改非常有用,因为“status”可以显示“deprecated”。例如,以下情况是我们想要将 API URL 从“/v2.1/{project_id}/old-resource”更改为“/v2.1/{project_id}/new-resource”的情况
{
"resources": {
"https://docs.openstack.org/api/openstack-compute/2.1/rel/old-resource": {
"href-template": "/v2.1/{project_id}/old-resource",
"hints": {
"status": "deprecated",
"allow": ["GET", "POST", "PUT", "DELETE"],
},
[..]
},
"https://docs.openstack.org/api/openstack-compute/2.1/rel/new-resource": {
"href-template": "/v2.1/{project_id}/new-resource",
"hints": {
"allow": ["GET", "POST", "PUT", "DELETE"],
},
[..]
}
}
}
当前的 JSON-Home(draft-03)并未涵盖可以提供请求/响应主体格式的功能。因此,在本规范中,Nova 将仅提供 API URL 和 HTTP 方法,不包括这些格式。在 openstack-dev ML 讨论中,我们有一个想法,即使用“hints”的 JSON-Home 提供 JSON-Schema API 定义(JSON-Home 上的 JSON-Schema)作为 OpenStack 特定的功能。但是,该功能不在本规范的范围内,本规范涵盖 JSON-Home 的标准范围,不包括 JSON-Schema。该功能需要其他规范,我们需要在项目之间讨论它。
API 路由器类已经包含 JSON-Home 所需的必要信息,我们可以通过将信息安排为 JSON-Home 格式并将其发布给客户端来实施 JSON-Home 功能。
在 v2.1 + 微版本中,我们将能够添加/删除 API URL 和请求/响应主体。此 JSON-Home 功能提供每个微版本可用的 API URL,这些 URL 在 header 中的 “X-OpenStack-Nova-API-Version” 中指定。如果不指定微版本,此功能将提供最小微版本的可用 API URL。“JSON-Home 上的 JSON-Schema”也将基于相同的语义提供指定微版本的可用请求/响应主体。
备选方案¶
已经存在“list extensions” API 用于获取可用的扩展列表,但该列表并非通用格式,如果需要 API 扩展发现,则需要在客户端实施成本。
数据模型影响¶
无。
REST API 影响¶
方法的规范
描述
API 扩展发现
方法类型
GET
正常的 HTTP 响应代码
HTTP200(OK)。这与 Keystone 的相同。
预期的错误 http 响应代码
HTTP404(NotFound)。如果指定的 API URL 不存在。
资源的 URL
/v2.1 及以下
如果允许,则为 body 数据定义 JSON schema
不允许请求体。
如果存在,则为响应数据定义 JSON schema
{
'type': 'object',
'properties': {
'resources': {
'type': 'object',
'patternProperties': {
'^https://docs.openstack.org/api/openstack-compute/.*$': {
'type': 'object',
'properties': {
'href': {'type': 'string'},
'href-template': {'type': 'string'},
'href-vars': {'type': 'object'},
'hints': {'type': 'object'}
},
'oneOf': [
{'required': ['href']},
{'required': ['href-template']}
],
'additionalProperties': False
}
}
}
},
'required': ['resources'],
'additionalProperties': False
}
安全影响¶
无。API URL 是公共信息。
通知影响¶
无。
其他最终用户影响¶
无。
性能影响¶
无。此功能仅向客户端提供静态数据,因此 Nova 无需承担性能成本。
其他部署者影响¶
无。
开发人员影响¶
此功能应从存储在 API 路由器中的 API 路由信息中实施。因此,开发者不需要仅为此功能实施任何代码,此功能的维护成本为零。
实现¶
负责人¶
- 主要负责人
oomichi
- 其他贡献者
无
工作项¶
添加一种将 API 路由信息转换为 JSON-Home 格式的方法。
添加一种处理 JSON-Home 请求的 accept header 方法。
依赖项¶
无。
测试¶
Keystone 已经实施了此功能,并且 Keystone 团队计划实施 Tempest 测试以进行 JSON-Home 测试。理想情况下,Nova 的此功能将使用与 Keystone 相同的 Tempest 测试机制,并在 gate 上测试 JSON-Home。如果这样做,我们可以减少 Tempest 上的测试代码,并验证项目之间的 JSON-Home 一致性。
文档影响¶
尚无。我们可以使用此功能获取 API URL、HTTP 方法(GET、POST、..),但 API 文档还需要请求/响应主体格式,而本规范并未将其作为第一步涵盖。提供请求/响应主体格式的功能将在项目之间讨论的其他规范中进行讨论。之后,我们将能够以不同项目中的相同方式获取 API 文档,这将是理想的情况。