Apps/AITC
This document specifies Apps-In-The-Cloud (AITC), a service for storing a user's list of Open Web Apps. This is meant to supersede the AppSync Spec.
Overview
The AITC Service is considered authoritative for the user's list of Web Apps and Device Information. In general, a client can safely overwrite its list of apps with that provided by the server, though it will rarely need to be so blunt. Beyond the list of apps and specific per-device configuration, the AITC Service does not store data for which it is not authoritative. For example, it stores only an app's manifest URL, not its whole manifest.
A few assumptions are made in this design:
- adding/removing/reorganizing apps is a rare occurrence compared to turning on a device.
- if an app is unavailable, it is okay to temporarily fail to display it to the user in her list of apps.
Document Formats
Documents are JSON.
App
{ origin: "https://example.com", manifestPath: "/manifest.webapp", installOrigin: "https://marketplace.mozilla.org", installedTime: 1330535996745, modificationTime: 1330535996945, receipts: ["...", "..."] }
- manifestPath is where the manifest was found (relative to the origin)
- receipts is always an array, with 0 or more elements.
- installedTime and modificationTime are millisecond timestamps
An App is later represented by its appid, which is the base64url-encoded App Origin with no b64 padding.
An Abbreviated App document contains only the origin and modification time:
{ origin: "https://example.com", modificationTime: 1330535996945 }
Device
{ uuid: "75B538D8-67AF-44E8-86A0-B1A07BE137C8", name: "Anant's Mac Pro", type: "mobile", layout: "android/phone", addedAt: "2012-02-28 12:23:35Z", modifiedAt: "2012-03-05 13:23:34Z", apps: {} }
- apps is a JSON blob that may indicate various screens of apps, and the order of apps within each screen. It may be fairly large. The apps object can only really be understood relative to the layout: it will contain information about applications and how they are arranged, and how that arrangement looks and what structure it has is layout-dependent (for instance, Android has multiple screens, with icons laid out on those screens; another device may have a single desktop but with arbitrary pixel-based placement, and so on).
An abbreviated device document is everything without the apps field, which could be quite large. This is sufficient for cases when you want to simply select a device (which requires at least name and uuid, and type might also be useful for some selectors).
Arrays
We never actually return JSON arrays (security problem on older browsers, and difficult to extend).
Instead, we return a JSON object with a top-level key whose value is the array in question. Specifically:
{apps: [..]}
or
{devices: [..]}
REST API
Authentication
Authentication uses BrowserID REST Auth.
POST /auth {assertion}
returns a JSON object:
{ id: "...", key: "...", endpoint: "https://node12.apps.services.mozilla.com/aitc/user/123" }
- id and key are the key identifier and key itself used for MAC Auth.
- endpoint is the prefix for all subsequent API calls
Apps
List Apps
GET {endpoint}/apps/
returns a JSON array of Abbreviated Apps, with format defined above.
GET {endpoint}/apps/?detailsafter={timestamp}
returns a JSON array of Full Apps that have been modified since that timestamp.
Remember, by JSON array, we mean an object with one key:
{apps: [...]}
Add/Update App
PUT {endpoint}/apps/{appid} {app_document}
NOTE: consider adding detection of stale version, e.g. if two receipts uploaded at same time.
Remove App
DELETE {endpoint}/apps/{appid}
Devices
List Devices
GET {endpoint}/devices/
returns a JSON array of abbreviated devices.
Single Device
GET {endpoint}/devices/{uuid}
returns a full device document
Add/Update Device
PUT {endpoint}/devices/{uuid} {device_document}
server ensures that the UUID is properly formed.
Delete Device
DELETE {endpoint}/devices/{uuid}
Optimization
Listing of Apps and Devices can be qualified with a standard HTTP header:
If-Modified-Since: Tuesday, 28 Oct 2012 19:43:31 GMT
As per the HTTP spec, if the date does not properly parse, or if the list has been modified since that date, then the output is exactly as specified above already. However, if the list has not changed, then the server returns a 304 not-modified response with no body.
QUESTION: should we use etags instead?