Key Points
The ability for server and client implementions to clearly communicate which version of the OpenSocial specification a particular Service API and resource supports is critical.
For the purpose of clearly identifying which version of the OpenSocial specification a particular application is implementing, a Web Link header referencing the base URI of the OpenSocial specification and using a rel attribute value of "implements" SHOULD be included within the HTTP request and response message.
For example, the Link would appear within the request:
GET /api/people/@me/@self HTTP/1.1 Host: example.org Link: <http://opensocial.org/specs/3.0>; rel="implements" |
And within the response:
HTTP/1.1 200 OK Link: <http://opensocial.org/specs/3.0>; rel="implements" |
A server MAY choose to implement additional conventions for identifying the current version, such as including a version indicator within the base URI of the Service API (e.g. http://example.org/v3/api/people). Such conventions are considered out of scope.
When a server implementation of an older version of the OpenSocial specification upgrades to a newer version, it has the responsibility to provide a clear mechanism for either continuing to support client applications using the old version or help clients migrate to the new.
Whether a server chooses to continue to support the old and new versions of the OpenSocial specification simultaneously is an implementation and business decision that is out of the scope of this specification.
However, when a server wishes to indicate to a client application that the server has been upgraded and that the old version of the API is no longer available, it SHOULD do so using an Upgrade Required response.
An "Upgrade Required Response" is an HTTP response that uses the 426 Upgrade Required status along with an "implements" Web Link. For instance:
HTTP/1.1 426 Upgrade Required Upgrade: OpenSocial/3.0 Connection: upgrade Link: <http://opensocial.org/specs/3.0>; rel="implements" |
Use of the 426 Upgrade Required response implies a complete cutover from one version of the specification to another. Alternatively, a server can choose to migrate client applications incrementally, initially deploying the new version of the application side-by-side with the old. Such a transition may or may not occur "in place", that is, requiring changes to the URI's a client uses to access the service.
For example, if a server currently exposes version 3.0 of the OpenSocial Profile Service at the URI "http://example.org/api/people", and it wishes to upgrade clients to a hypothetical version 3.1 in the future, without requiring clients to change the URIs they use to access the service, it can either continue to support the 3.0 clients transparently or perform an "in place" upgrade.
An example 3.0 client request:
GET /api/people/@me/@self HTTP/1.1 Link: <http://opensocial.org/specs/3.0>; rel="implements" |
A server implementing the hypothetical 3.1 version of the OpenSocial spec can continue to respond as if it was a 3.0 implementation:
HTTP/1.1 200 OK Link: <http://opensocial.org/specs/3.0>; rel="implements" Content-Type: application/json {... OpenSocial 3.0 data ...} |
Or, it can perform an "in-place" upgrade:
HTTP/1.1 200 OK Upgrade: OpenSocial/3.1 Connection: upgrade Link: <http://opensocial.org/specs/3.1>; rel="implements" Content-Type: application/json {... OpenSocial 3.1 data ...} |
Alternatively, the server MAY choose to deploy the new version with a new URI.
An example 3.0 client request:
GET /v3.0/api/people/@me/@self HTTP/1.1 Link: <http://opensocial.org/specs/3.0>; rel="implements" |
An upgrade redirection from the server:
HTTP/1.1 301 Moved Permanently Location: /v3.1/api/people/@me/@self HTTP/1.1 Upgrade: OpenSocial/3.1 Connection: upgrade Link: <http://opensocial.org/specs/3.1>; rel="implements" |
Implementors of client applications MAY use the Prefer HTTP Header within a request to indicate the preferred mechanism for upgrade handling.
This specification registers the following new Prefer header token values:
These Preference tokens MAY be used together.
For example, a client can indicate to the server that it is capable of handling automatic in-place upgrade for any 3.* version of the specification but prefers use of the 426 Upgrade Required response for all other cases:
GET /api/people/@me/@self HTTP/1.1 Link: <http://opensocial.org/specs/3.1>; rel="implements" Prefer: return-upgrade-required, upgrade-in-place=3.* |
Or, for instance, a client can indicate that is is capable of handling automatic in-place upgrades for any 3.* version and prefers use of redirects for all other cases:
GET /api/people/@me/@self HTTP/1.1 Link: <http://opensocial.org/specs/3.1>; rel="implements" Prefer: upgrade-redirect, upgrade-in-place=3.* |
Key Points
First... let's introduce an OpenSocial Media Type to represent the OS 3.x Data Model.
JSON Data Model
application/vnd.opensocial.data.3+json |
XML Data
application/vnd.opensocial.data.3+xml |
The ".3" portion of the Media Type indicates the major version of the OpenSocial Format. The assumption is that all minor versions would maintain fundamental data model and format compatibility within a single major (e.g. 3.2 would be backwards compatible with 3.1 and 3.0, etc) therefore we eliminate the need to mint a new media type for each minor update.The media type would be used within HTTP requests and responses to indicate the supported version.
For instance, if a client wishes to notify the server that it implements version 3.0 of the OS specification but will accept down-level versions of the data format if necessary, it can send the following request:
GET /api/people/@me/@self HTTP/1.1 Host: example.org Link: <http://opensocial.org/specs/3.0>; rel="implements" Prefer: upgrade-in-place=3.* Accept: application/vnd.opensocial.data.3+json, application/vnd.opensocial.data.3+xml, application/json;q=0.5 |
A server examining this request can determine unambiguously what version of the OS protocol and data model the client supports and what the client's preferences are as far as data model and protocol behavior. If this request is sent to a downlevel (2.x) version server, the Link, Prefer and Accept headers are most likely to be ignored and a typical 2.x response would be generated – which is acceptable to the client given the construction of the request. If the server supports 3.x it will return an expected 3.x response. If the server happens to support a future hypothetical version (e.g. 4.x), then it can decide to either a) respond to the request as if it were 3.x, b) attempt to do an inline upgrade to 4.x and c) reject the request and ask the client to upgrade.
Using a media type, however, only addresses part of the problem. It is often the case that data being processed can become disconnected from the request context (e.g. the media type is no longer available). It is helpful in such situations for the data format / model itself to directly indicate which version of the specification is supported. For this, I propose that we leverage the same "implements" link relation used in the Link header... within the XML serialization, this would manifest as an atom:link element, e.g. <link rel="implements" href="http://opensocial.org/specs/3.0" />. Within JSON, we need to get a bit creative since there currently are no defined standards for representing links in JSON; my suggestion based on general discussion would be use a "$rel" naming convention, e.g. "$implements":"http://opensocial.org/specs/3.0".
For example, within any OS 3.0 JSON serialization, it would be:
{ "$implements":"http://opensocial.org/specs/3.0", "id":"example.org:...", "displayName":"Jane", ... } |
If multiple versions need to be specified, the value can be an array (e.g. "$implements":["...","..."] )
Section 8 of the Core Gadget spec document provides a rudimentary mechanism for specifying which version of the specification a gadget spec implements along with which versions of features. What the Core Gadget spec fails to do, however, is deal with versioning of the Gadget XML document format itself. At an absolute minimum, a MIME Media Type is required:
application/vnd.opensocial.gadget.3+xml |
The Embedded Experiences document media type should be updated to reflect both the versioning requirement and feedback provided by the IETF Mime Media Types mailing list suggesting that all OpenSocial related Mime types use the vnd.opensocial convention. This would change the EE Doc media types from "application/embed+xml" and "application/embed+json" to:
application/vnd.opensocial.embed.3+xml |
and
application/vnd.opensocial.embed.3+json |
Optionally, as a best practice, we should define media types for all the various document types we have, including the Message Bundle defined in the Core Gadget spec.
appication/vnd.opensocial.message.3+xml |
Additionally, we should have a media type for the Template Library format...
application/vnd.opensocial.templates.3+xml |