/version/{catalogy}/{entities}/{entity_id}/action
其中
version : API 版本, 如 v1, v2, v3 等
group : 某种分类, 如 configuration, manage 等高层资源
entities : 实体资源, 如 images, services, networks 等, 为复数
entity_id : 实体资源的 id
action : 表示对资源的某种行为, 具体的行为在 body 中指定.
/v1/images/{image_id}/members/{member_id}
/v1/images/{image_id}/members
/v3/{project_id}/groups/{group_id}/action : 对资源进行状态修改
{
“reset_status”: {
“status”: “available”
}
}
请求参数在 ? 之后以 key=value&key=value 形式存在
排序
分页
过滤
基于以上参数提供 AND 的语义, 对于 OR 语义, 可选支持(客户端可以将多个操作合并, 间接实现 OR 语义)
limit=2&marker=1234&page_reverse=false
/v2.0/networks.json?limit=2&page_reverse=false HTTP/1.1
{
"networks": [
{
"admin_state_up": true,
"id": "396f12f8-521e-4b91-8e21-2e003500433a",
"name": "net3",
"provider:network_type": "vlan",
"provider:physical_network": "physnet1",
"provider:segmentation_id": 1002,
"router:external": false,
"shared": false,
"status": "ACTIVE",
"subnets": [],
"tenant_id": "20bd52ff3e1b40039c312395b04683cf"
"project_id": "20bd52ff3e1b40039c312395b04683cf"
},
{
"admin_state_up": true,
"id": "71c1e68c-171a-4aa2-aca5-50ea153a3718",
"name": "net2",
"provider:network_type": "vlan",
"provider:physical_network": "physnet1",
"provider:segmentation_id": 1001,
"router:external": false,
"shared": false,
"status": "ACTIVE",
"subnets": [],
"tenant_id": "20bd52ff3e1b40039c312395b04683cf"
"project_id": "20bd52ff3e1b40039c312395b04683cf"
}
],
"networks_links": [
{
"href": "http://127.0.0.1:9696/v2.0/networks.json?limit=2&marker=71c1e68c-171a-4aa2-aca5-50ea153a3718",
"rel": "next"
},
{
"href": "http://127.0.0.1:9696/v2.0/networks.json?limit=2&marker=396f12f8-521e-4b91-8e21-2e003500433a&page_reverse=True",
"rel": "previous"
}
]
}
其中 networks_links 中指明下一页的链接, 上一页的链接. 最后一页没有 next 链接,
第一页没有 previous 链接
GET / : 列出所有版本
{
"versions": [
{
"status": "CURRENT",
"updated": "2012-01-04T11:33:21Z",
"id": "v1.0",
"links": [
{
"href": "http://23.253.228.211:8776/v1/",
"rel": "self"
}
]
},
{
"status": "CURRENT",
"updated": "2012-11-21T11:33:21Z",
"id": "v2.0",
"links": [
{
"href": "http://23.253.228.211:8776/v2/",
"rel": "self"
}
]
}
]
}
其中 updated 是可选的
GET /v3 : 列出 v3 信息
{
“version”: {
“id”: “v3.4”,
“links”: [
{
“href”: “http://localhost:35357/v3/”,
“rel”: “self”
}
],
“media-types”: [
{
“base”: “application/json”,
“type”: “application/vnd.openstack.identity-v3+json”
}
],
“status”: “stable”,
“updated”: “2015-03-30T00:00:00Z”
}
}
应答体中应该但不仅限于如下字段
时间格式
格式为 IOS8601
即 CCYY-MM-DDThh:mm:ss±hh:mm, 例如 2015-08-27T09:49:58-05:00.
如果包含 ±hh:mm 表示相对 UTC 的偏移
注:
应答体 key 中单词统一为小写, 如果是多个单词组成, 以 “_” 分割. 如 created_at, updated_at 等
应答体 value 中单词统一为小写, 如果是多个单词组成, 以 “-” 分割.
对应 POST 创建资源, 返回体中必须包含资源的 id
GET /v2/images
{
"images": [
{
"status": "active",
"name": "cirros-0.3.2-x86_64-disk",
"created_at": "2014-11-07T17:07:06Z",
"updated_at": "2014-11-07T17:19:09Z",
"visibility": "public",
"self": "/v2/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27",
"id": "1bea47ed-f6a9-463b-b423-14b9cca9ad27",
"schema": "/v2/schemas/image"
},
{
"status": "active",
"name": "F17-x86_64-cfntools",
"created_at": "2014-10-30T08:23:39Z",
"updated_at": "2014-11-03T16:40:10Z",
"visibility": "public",
"self": "/v2/images/781b3762-9469-4cec-b58d-3349e5de4e9c",
"id": "781b3762-9469-4cec-b58d-3349e5de4e9c",
"schema": "/v2/schemas/image"
}
],
"schema": "/v2/schemas/images",
"first": "/v2/images"
}
GET /v2/images/{image_id}
{
“image”: {
“checksum”: “eb9139e4942121f22bbc2afc0400b2a4”,
“container_format”: “bare”,
“created_at”: “2016-03-15T15:09:07.000000”,
“deleted”: false,
“deleted_at”: null,
“disk_format”: “vmdk”,
“id”: “1086fa65-8c63-4081-9a0a-ddf7e88e485b”,
“is_public”: false,
“min_disk”: 22,
“min_ram”: 11,
“name”: “Silas Marner”,
“owner”: “c60b1d57c5034e0d86902aedf8c49be0”,
“properties”: {
“foo”: “bar”,
“qe_status”: “approved”
},
“protected”: false,
“size”: 25165824,
“status”: “active”,
“updated_at”: “2016-05-10T21:14:04.000000”,
“virtual_size”: null
}
}
注: images 的 value 为数组, 而不是直接数组
## 同步或异步
异步操作, 立马返回, API 服务确保后面的操作按照期望在进行, 客户端可以通过 status
属性查看当前进度或状态
## 批量操作
与单个接口不同之处 1. 仅仅指定多个对象; 2. 要不全部成功, 要不全部失败
## HTTP 状态码
GET 获取资源 正常返回 201
DELETE 删除资源 正常返回 202
POST 创建资源 正常返回 202
401 Unauthorized : 没有认证
403 Forbidden : 没有权限进行操作
404 Not Found : 没有找到对应的 URL 或资源
405 : 不支持该操作
409 Conflict : 冲突
500 Internal server error
503 Service unavailable
## API 文档要求
1. URL
2. 可能的 URL 参数
3. 请求 body
4. 应答 body
5. 正常返回状态, 错误返回状态
6. 例子, 包括正常, 异常
## 多对象之间关联
通过 id 相互关联
GET /v2.0/fw/firewall_rules/{firewall_rule_id}
{
"firewall_rule": {
"action": "allow",
"description": "",
"destination_ip_address": null,
"destination_port": "80",
"enabled": true,
"firewall_policy_id": null,
"id": "8722e0e0-9cc9-4490-9660-8c9a5732fbb0",
"ip_version": 4,
"name": "ALLOW_HTTP",
"position": null,
"protocol": "tcp",
"shared": false,
"source_ip_address": null,
"source_port": null,
"project_id": "45977fa2dbd7482098dd68d0d8970117",
"tenant_id": "45977fa2dbd7482098dd68d0d8970117"
}
}
## 参考
https://developer.openstack.org/api-ref/block-storage/v3/index.html?expanded=list-backups-with-detail-detail
https://docs.atlassian.com/jira/REST/cloud/#api/2/worklog-getWorklogsForIds
http://json-schema.org/latest/json-schema-hypermedia.html
## 附录
### 命名参考
请求体或应答体常用字段
size : 表示大小
count : 表示数量
status : 表示状态, 状态变化 creating, available, in-use, deleting, error(error when create), error_deleting
type : 表示类型
xx_type : 表示某个资源的类型
is_xxx: 对二义性资源的描述, 比如 is_public, is_active
percentage : 百分比
xx_items : 列表资源
xx_ips : 多个资源时, 名字加 "s"
xxx_bytes : 表示某个对象或资源大小, 建议增加单位
metadata : 元数据
xxx_format : 格式
visibility : public, private, shared, or community
expires_at : 过期时间, 参考 created_at
xxx_properties : 属性列表
admin_state_up : 管理状态 true, false
enabled : 某条规则生效 true, false
min_xxxx : 最小
max_xxxx : 最大
对应二义性的一定要用 true, false 而不是 1, 0
status :
active, deactived;
pending, accepted, rejected;
pending, processing, success, failure
active, down, build, error
## Neturon 元素
network
subnet
port
segment
trunk : subport -> segment
floatingip : subnet, port
route : 1. 多个 subnet 之间通过路由打通; 2. 通过 NAT 访问外边网络;
subnets
subnetpools
fw : 防火墙
## 例子
## 认证
GET /v3/auth/tokens
X-Auth-Token : TOKEN_ID
或
GET /v3/auth/token=TOKEN_ID
{
"token": {
"expires_at": "2013-02-27T18:30:59.999999Z",
"issued_at": "2013-02-27T16:30:59.999999Z",
"methods": [
"password"
],
"user": {
"domain": {
"id": "1789d1",
"links": {
"self": "http://identity:35357/v3/domains/1789d1"
},
"name": "example.com"
},
"id": "0ca8f6",
"links": {
"self": "http://identity:35357/v3/users/0ca8f6"
},
"name": "Joe"
}
}
}
### POST 请求
POST /v3/services
{
"service": {
"type": "volume"
}
}
{
"service": {
"enabled": true,
"id": "686766",
"links": {
"self": "http://identity:5000/v3/services/686766"
},
"type": "volume"
}
}
POST /v3/endpoints
{
"endpoint": {
"interface": "public",
"name": "name",
"region_id": "north",
"url": "http://identity:35357/v3/endpoints/828384",
"service_id": "686766"
}
}
{
"endpoint": {
"id": "828384",
"interface": "internal",
"links": {
"self": "http://identity:35357/v3/endpoints/828384"
},
"name": "the internal volume endpoint",
"region_id": "north",
"service_id": "686766",
"url": "http://identity:35357/v3/endpoints/828384"
}
}
返回的资源在 links 中
POST /v2.1/{tenant_id}/servers
{
"server": {
"name": "new-server-test",
"imageRef": "http://openstack.example.com/openstack/images/70a599e0-31e7-49b7-b260-868f441e862b",
"flavorRef": "http://openstack.example.com/openstack/flavors/1",
"metadata": {
"My Server Name": "Apache1"
},
"min_count": "2",
"max_count": "3"
}
}
{
"server": {
"adminPass": "wfksH3GTTseP",
"id": "440cf918-3ee0-4143-b289-f63e1d2000e6",
"links": [
{
"href": "http://openstack.example.com/v2.1/servers/440cf918-3ee0-4143-b289-f63e1d2000e6",
"rel": "self"
},
{
"href": "http://openstack.example.com/servers/440cf918-3ee0-4143-b289-f63e1d2000e6",
"rel": "bookmark"
}
]
}
}
返回的资源在 links 中的另外一种形式