Skip to content

Commit

Permalink
Merge pull request #140 from morphis/cleanup-ref-api
Browse files Browse the repository at this point in the history
Cleanup and restructure API reference overview
  • Loading branch information
keirthana authored Sep 11, 2024
2 parents f5c87a4 + 8f3ca7f commit 8f23747
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 178 deletions.
189 changes: 12 additions & 177 deletions reference/api-reference.md
Original file line number Diff line number Diff line change
@@ -1,194 +1,29 @@
(ref-api)=
# API reference

All communication between AMS and its clients happen using a RESTful API over HTTP. This API is encapsulated over either TLS (for remote operations) or a Unix socket (for local operations).
Anbox Cloud includes various APIs to help you build solutions with it. This page provides an overview of the available APIs and their uses.

## APIs and their structure
All these APIs except for the {ref}`anbox-https-api` have an auto-generated Open API specification describing its API endpoints.

Anbox Cloud provides the following APIs:
## Available APIs

* AMS HTTP API
* Anbox Cloud HTTP API
* Stream Gateway API
* Anbox Platform SDK API
### AMS HTTP API

All these APIs except for the {ref}`anbox-https-api` have an auto-generated specification describing its API endpoints.
The AMS services provide an HTTP based API to help you manage all of its objects. Internally the `amc` client uses the same API to perform its operation.

## Authentication
You can find the OpenAPI specification [here](https://canonical.github.io/anbox-cloud.github.com/latest/ams/).

Not all REST API endpoints require authentication, for example, the following API calls are allowed for everyone:
### Anbox HTTP API

* `GET /`
* `GET /1.0`
* `GET /1.0/version`
The Anbox runtime inside each instance managed by the AMS provides an HTTP API over a UNIX domain socket that helps interacting with various functionalities offered by Anbox. This includes the injection of position or sensor events into Android, among other things.

Some endpoints require an additional authentication token to ensure that the requester is authorised to access the resource, for example:
You can find the API specification at {ref}`anbox-https-api`.

* `GET /1.0/artifacts`
* `PATCH /1.0/instances/<name>`
### Anbox Stream Gateway API

## API versioning
The Anbox Stream Gateway service provides an API endpoint to help you to manage streaming sessions.

The details of a version of the API can be retrieved using `GET /<version>`. For example, `GET /1.0`.

If an API version is bumped to a major version, it indicates that backward compatibility is affected.

Feature additions done without breaking backward compatibility only result in additions to `api_extensions` which can be used by the client to check if a given feature is supported by the server.

## Return values

There are three standard return types:

* Standard return value
* Background operation
* Error

### Standard return value

For a standard synchronous operation, the following dict is returned:

```json
{
"type": "sync",
"status": "Success",
"status_code": 200,
"metadata": {}
}
```

HTTP response status code is 200.

### Background operation

When a request results in a background operation, the HTTP code is set to 202 (Accepted) and the Location HTTP header is set to the operation URL.

The response body is a dict with the following structure:

```json
{
"type": "async",
"status": "OK",
"status_code": 100,
"operation": "/1.0/containers/<id>",
"metadata": {}
}
```

The operation metadata structure looks like:

```json
{
"id": "c6832c58-0867-467e-b245-2962d6527876",
"class": "task",
"created_at": "2018-04-02T16:49:36.341463206+02:00",
"updated_at": "2018-04-02T16:49:36.341463206+02:00",
"status": "Running",
"status_code": 103,
"resources": {
"containers": [
"/1.0/containers/3apqo5te"
]
},
"metadata": null,
"may_cancel": false,
"err": ""
}
```

The body is mostly provided as a user friendly way of seeing what's going on without having to pull the target operation, all information in the body can also be retrieved from the background operation URL.

### Error

There are various situations in which something may immediately go wrong, in those cases, the following return value is used:

```json
{
"type": "error",
"error": "Failure",
"error_code": 400,
"metadata": {}
}
```

HTTP response status code is one of 400, 401, 403, 404, 409, 412 or 500.

## Status codes

The REST API often has to return status information, which could be the reason for an error, the current state of an operation or the state of the various resources it exports.

To make it simple to debug, there are two ways in which such information is represented - a numeric representation of the state which is guaranteed never to change and can be relied on by API clients and a text version so that it is easier for people manually using the API to understand better. In most cases, those will be called `status` and `status_code`, the former being the user friendly string representation and the latter being the fixed numeric value.

The codes are always 3 digits, with the following ranges:

* 100 to 199: resource state (started, stopped, ready, ...)
* 200 to 399: positive action result
* 400 to 599: negative action result
* 600 to 999: future use

### List of current status codes

Code | Meaning
---|------
100 | Operation created
101 | Started
102 | Stopped
103 | Running
104 | Cancelling
105 | Pending
106 | Starting
107 | Stopping
108 | Aborting
109 | Freezing
110 | Frozen
111 | Thawed
200 | Success
400 | Failure
401 | Cancelled

## Recursion

To optimise queries of large lists, recursion is implemented for collections. A `recursion` argument can be passed to a GET query against a collection.

The default value is 0 which means that collection member URLs are returned. Setting it to 1 will have those URLs be replaced by the object they point to (typically a dict).

Recursion is implemented by simply replacing any pointer to a job (URL) by the object itself.

## Async operations

Any operation which take more than a second must be done in the background, returning a background operation ID to the client. With this ID, the client is able to either poll for a status update or wait for a notification using the long-poll API.

## Notifications

A web-socket based API is available for notifications. Different notification types exist to limit the traffic going to the client. It is recommended that the client always subscribes to the *operations* notification type before triggering remote operations so that it doesn't have to continually poll for their status.

## PUT vs PATCH

PUT and PATCH APIs are supported to modify existing objects.

PUT replaces the entire object with a new definition, it's typically called after the current object state was retrieved through GET.

To avoid race conditions, the ETag header should be read from the GET response and sent as If-Match for the PUT request. Doing so makes the request fail if the object was modified between GET and PUT.

PATCH can be used to modify a single field inside an object by only specifying the property that you want to change. To unset a key, setting it to empty will usually do the trick, but there are cases where PATCH won't work and PUT needs to be used instead.

## Authorisation

Some operation may require a token to be included in the HTTP Authorisation header even if the request is already authenticated using a trusted certificate. If the token is not valid, the request is rejected by the server. This ensures that only authorised clients can access those endpoints.

Authorization: bearer <token>

## File upload

Some operations require uploading a payload. To prevent the difficulties of handling multipart requests, a unique file is uploaded and its bytes are included in the body of the request. The following metadata associated with the file is included in extra HTTP headers:

* X-AMS-Fingerprint: Fingerprint of the payload being added
* X-AMS-Request: Metadata for the payload. This is a JSON, specific for the operation.

## Instances and Containers

The documentation shows paths such as `/1.0/instances/...`, which were introduced with Anbox Cloud version 1.20.0. Older releases that supported only containers and not virtual machines supply the exact same API at `/1.0/containers/...`.

Although deprecated, the `1.0/containers/...` API is still available for backward compatibility.
You can find the OpenAPI specification [here](https://canonical.github.io/anbox-cloud.github.com/latest/anbox-stream-gateway).

```{toctree}
:hidden:
Expand Down
2 changes: 1 addition & 1 deletion reference/network-ports.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ For the Anbox Cloud Appliance, ports are exposed only for accessing the Anbox Cl
| AMS API | 8444 | TCP | no | yes | API endpoint for the AMS service |
| NATS | 4004 | TCP | no | yes | API endpoint for the [NATS](https://nats.io) message queue |
| Anbox Stream Gateway | 9031 | TCP | no | yes | API endpoint for the Anbox Stream Gateway |
| Anbox Stream Agent | 9033 | TCP | no | yes | API endpoint for the Anbox Strem Agent |
| Anbox Stream Agent | 9033 | TCP | no | yes | API endpoint for the Anbox Stream Agent |
| Anbox Cloud Dashboard | 5000 | TCP | no | yes | Endpoint providing access to the UI |

0 comments on commit 8f23747

Please sign in to comment.