API Working Group/Current Design/Links

= Analysis =

How are links being referenced in OpenStack APIs

= Current Design =

Cinder
Cinder API reference

Cinder appears to use the JSON Hyper-Schema style for all embedded link references.

Examples
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" }           ]        }    ] }

GET /v2/{tenant_id}/volumes

{   "volumes": [ {           "id": "45baf976-c20a-4894-a7c3-c94b7376bf55", "links": [ {                   "href": "http://localhost:8776/v2/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/45baf976-c20a-4894-a7c3-c94b7376bf55", "rel": "self" },               {                    "href": "http://localhost:8776/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/45baf976-c20a-4894-a7c3-c94b7376bf55", "rel": "bookmark" }           ],            "name": "vol-004" },       {            "id": "5aa119a8-d25b-45a7-8d1b-88e127885635", "links": [ {                   "href": "http://localhost:8776/v2/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/5aa119a8-d25b-45a7-8d1b-88e127885635", "rel": "self" },               {                    "href": "http://localhost:8776/0c2eba2c5af04d3f9e9d0d410b371fde/volumes/5aa119a8-d25b-45a7-8d1b-88e127885635", "rel": "bookmark" }           ],            "name": "vol-003" }   ] }

Glance
Glance API reference

Glance is using JSON Hyper-Schema style references for its home page.

In most other requests and responses, glance consistently uses the keys "self", "file", "schema", and "first" to record relative URLs. These fields do not appear to use fully qualified URLs with a protocol and hostname.

Examples
GET /

{   "versions": [ {           "status": "CURRENT", "id": "v2.2", "links": [ {                   "href": "http://23.253.228.211:9292/v2/", "rel": "self" }           ]        },        {            "status": "SUPPORTED", "id": "v2.1", "links": [ {                   "href": "http://23.253.228.211:9292/v2/", "rel": "self" }           ]        },        {            "status": "SUPPORTED", "id": "v2.0", "links": [ {                   "href": "http://23.253.228.211:9292/v2/", "rel": "self" }           ]        },        {            "status": "SUPPORTED", "id": "v1.1", "links": [ {                   "href": "http://23.253.228.211:9292/v1/", "rel": "self" }           ]        },        {            "status": "SUPPORTED", "id": "v1.0", "links": [ {                   "href": "http://23.253.228.211:9292/v1/", "rel": "self" }           ]        }    ] }

GET /v2/images

{   "images": [ {           "status": "active", "name": "cirros-0.3.2-x86_64-disk", "tags": [], "container_format": "bare", "created_at": "2014-11-07T17:07:06Z", "disk_format": "qcow2", "updated_at": "2014-11-07T17:19:09Z", "visibility": "public", "self": "/v2/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27", "min_disk": 0, "protected": false, "id": "1bea47ed-f6a9-463b-b423-14b9cca9ad27", "file": "/v2/images/1bea47ed-f6a9-463b-b423-14b9cca9ad27/file", "checksum": "64d7c1cd2b6f60c92c14662941cb7913", "owner": "5ef70662f8b34079a6eddb8da9d75fe8", "size": 13167616, "min_ram": 0, "schema": "/v2/schemas/image", "virtual_size": null },       {            "status": "active", "name": "F17-x86_64-cfntools", "tags": [], "container_format": "bare", "created_at": "2014-10-30T08:23:39Z", "disk_format": "qcow2", "updated_at": "2014-11-03T16:40:10Z", "visibility": "public", "self": "/v2/images/781b3762-9469-4cec-b58d-3349e5de4e9c", "min_disk": 0, "protected": false, "id": "781b3762-9469-4cec-b58d-3349e5de4e9c", "file": "/v2/images/781b3762-9469-4cec-b58d-3349e5de4e9c/file", "checksum": "afab0f79bac770d61d24b4d0560b5f70", "owner": "5ef70662f8b34079a6eddb8da9d75fe8", "size": 476704768, "min_ram": 0, "schema": "/v2/schemas/image", "virtual_size": null }   ],    "schema": "/v2/schemas/images", "first": "/v2/images" }

Keystone
Keystone API reference

Keystone is using the JSON Hyper-Schema style reference for some links that it returns.

There are some requests and responses that use the keyword "self" when referring to resource links, these appear within a "links" dictionary that looks similar to the JSON Hyper-Schema style. These "links" dictionaries may also contain "next" and "previous" links.

There are also some responses which use the "self" keyword and the "url" keyword. The "url" key appears to occur in requests as well as responses.

The majority of calls appear to use the "self" keyword wrapped in the "links" dictionary, as follows:

{   "links": { "self": "http://spam:eggs/bacon" } }

Examples
GET /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" } }

GET /v3/auth/tokens

{   "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 /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" } }

GET /v3/services

{   "links": { "next": null, "previous": null, "self": "http://identity:5000/v3/services" },   "services": [ {           "description": "Keystone Identity Service", "enabled": true, "id": "686766", "links": { "self": "http://identity:5000/v3/services/686766" },           "name": "keystone", "type": "identity" },       {            "enabled": true, "id": "936521", "links": { "self": "http://identity:5000/v3/services/936521" },           "type": "volume" }   ] }

Neutron
Neutron API reference

Neutron uses the JSON Hyper-Schema for returned responses. Aside its home and version pages, neutron does not return embedded links in its responses.

Examples
GET /

{   "versions": [ {           "status": "CURRENT", "id": "v2.0", "links": [ {                   "href": "http://23.253.228.211:9696/v2.0", "rel": "self" }           ]        }    ] }

Nova
Nova API reference

Nova appears to use the JSON Hyper-Schema for most returned responses.

There are a few responses that use the "url" key to describe a link, it is not clear if these are only for external resources.

There are also a few calls which allow the values "imageRef" and "flavorRef" to accept incoming links.

Examples
GET /

{   "versions": [ {           "id": "v2.0", "links": [ {                   "href": "http://openstack.example.com/v2/", "rel": "self" }           ],            "status": "SUPPORTED", "version": "", "min_version": "", "updated": "2011-01-21T11:33:21Z" },       {            "id": "v2.1", "links": [ {                   "href": "http://openstack.example.com/v2.1/", "rel": "self" }           ],            "status": "CURRENT", "version": "2.3", "min_version": "2.1", "updated": "2013-07-23T11:33:21Z" }   ] }

POST /v2.1/​{tenant_id}​/os-agents

{   "agent": { "hypervisor": "hypervisor", "os": "os", "architecture": "x86", "version": "8.0", "md5hash": "add6bb58e139be103324d04d82d8f545", "url": "http://example.com/path/to/resource" } }

{   "agent": { "agent_id": 1, "architecture": "x86", "hypervisor": "hypervisor", "md5hash": "add6bb58e139be103324d04d82d8f545", "os": "os", "url": "http://example.com/path/to/resource", "version": "8.0" } }

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" }       ]    } }

= References =