指定/蓝图/APIv2结构化数据
概述
| Gerrit补丁 | [1] |
|---|---|
| Launchpad蓝图 | [2] |
| API v2 规范 | [3] |
本蓝图建议定义 API v2 响应的结构化数据格式。
API 资源
这里提供了一个结构化和文本表示形式的示例,用于说明意图,使用 SRV 记录。我们将默认使用文本表示形式(?),并在 Accept/Content-Type 标头中使用 VND mime-type 来区分提供的/请求的请求/响应格式
请求
GET https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id}/records HTTP/1.1 Host: dns.provider.com Accept: application/vnd.openstack.designate-v2-structured+json X-Auth-Token: *****
响应
HTTP/1.1 200 OK Vary: Accept Content-Type: application/vnd.openstack.designate-v2-structured+json
{
"records": [{
"id": " ... ",
"data": {
"weight": 0,
"priority": 10,
"port": 7778,
"target": "xmpp1.example.org."
}
}, {
"id": " ... ",
"data": {
"weight": 0,
"priority": 20,
"port": 7778,
"target": "xmpp2.example.org."
}
}]
}
请求
GET https://dns.provider.com/v2/zones/{zone-id}/recordsets/{recordset-id}/records HTTP/1.1 Host: dns.provider.com Accept: application/json X-Auth-Token: *****
响应
HTTP/1.1 200 OK Vary: Accept Content-Type: application/json
{
"records": [{
"id": " ... ",
"data": "0 10 7778 xmpp1.example.org."
}, {
"id": " ... ",
"data": "0 20 7778 xmpp2.example.org."
}]
}
实现
每个 RRType(例如 A、AAAA、SRV)将实现为单独的类,包含验证和文本与结构化表示形式之间的转换。这些类将在启动时通过插件机制被需要它们的的服务枚举(例如 API 服务)。例如
class SRV(rrtype.RRType):
"""
SRV Resource Record Type
Defined in: RFC2782
"""
__plugin_name__ = 'SRV'
""" The RFC defined type code for the RRType """
TYPE = 33
""" A regular expression using named captures to extract the fields from a textual representation of the RData """
RE_TEXT = r"(?P<priority>\d+) (?P<weight>\d+) (?P<port>\d+) (?P<target>.+)"
""" A formatting string used to reconstructed the textual representation of the RData from a set of named fields """
FM_TEXT = "%(priority)d %(weight)d %(port)d %(target)d"
""" The Valdiation schema for this RRType, validates against the structured format """
SCHEMA = {
"$schema": "https://schema.json.js.cn/draft-04/hyper-schema",
"additionalProperties": False,
"required": ["priority", "weight", "port", "target"],
"properties": {
"priority": {
"type": "integer",
"min": 0,
"max": 65535
},
"weight": {
"type": "integer",
"min": 0,
"max": 65535
},
"port": {
"type": "integer",
"min": 0,
"max": 65535
},
"target": {
"type": "string",
"format": "hostname"
}
}
}
def __init__(self, priority=None, weight=None, port=None, target=None):
super(SRV, self).__init__()
self.priority = priority
self.weight = weight
self.port = port
self.target = target
@classmethod
def from_text(self, t):
""" Implemented in the base class, uses the RE_TEXT regex to construct a new object """
pass
@classmethod
def from_dict(self, d):
""" Implemented in the base class, constructs a new object based on the supplied dict, using the classes constructor """
pass
def to_text(self, t):
""" Implemented in the base class, uses the FM_TEXT to construct the textual representation of this object """
pass
def to_dict(self, d):
""" Implemented in the base class, constructs a dict representation of this object """
pass
API 层将在将所有 RData 发送到 central 之前,将其转换为这些类。这允许 API 层利用每种 rrtype 的验证。此外,central(存储?)将使用这些对象响应所有记录 CRUD 方法,允许 API 选择适当的响应格式。
数据库模式
目前不会进行任何更改。
未来,我们可能会选择将结构化格式存储在数据库中 - 要么作为 JSON/Pickle blob,要么为每个 RRType 定义一个明确的表。关于此的细节,以及是否对数据库模式进行任何更改的决定,超出了本蓝图的范围。
评审意见
参考:https://wiki.openstack.org/wiki/VersionDiscovery#media-types 我们是否应该考虑在 VND 中添加一个 mime-type 属性(例如 version=1.0),以便将来更容易地更改类型,如果需要,而不会破坏现有用户?例如:application/vnd.openstack.designate-v2-structured+json 变为 application/vnd.openstack.designate-v2-structured+json;version=1.0 这样,如果我们需要,就可以使用 application/vnd.openstack.designate-v2-structured+json;version=2.0,而不会影响不想迁移到新结构的的用户。[eankutse]