One feature we added in OpenSocial 0.9 is Albums. Albums include MediaItems: photos, movies, and songs. Several of the containers out there, including MySpace, already had different views of what an album is. For example, on our platform you can access an album today via the REST URI (/v1/users/[user id]/albums/[album id]) (docs here). The big benefit of OpenSocial is that the group standardizes how all this works so that an application written for MySpace using only OpenSocial APIs should work for Orkut, Hi5, Yahoo!, or any other container. Album support was introduced in a few different areas:
- Support to the OpenSocial JavaScript library.
- Support to the RESTful API
- Support in the OpenSocial RPC library (an optional part of the spec not supported by MySpace at this time)
Let's take a look at the required parts of the albums support.
JavaScript changes
First, we added a bunch of new methods to fetch, add, update, and remove Albums and MediaItems. First, the methods that allow one to fetch information:
- opensocial.newFetchAlbumsRequest(idSpec, opt_params): Creates an object for DataRequest to request albums. opt_params can specify the following:
- o opensocial.Album.Field.ID - an array of album Ids to fetch (fetch all albums if empty, subject to pagination)
- o opensocial.Album.Field.MEDIA_TYPE - an array of MediaItem.TYPE values to specify the kind of Albums to fetch.
- opensocial.newFetchMediaItemsRequest(idSpec, albumId, opt_params): Fetches the list of media items in an Album. opt_params can specify the following:
- o opensocial.MediaItem.ID - an array of media item ids to selectively fetch (fetch all items if empty, subject to pagination)
- o opensocial.MediaItem.MEDIA_TYPE - an array of MediaItem.TYPE values to specify the types of MediaItems to fetch
The usual Filter / FIRST / MAX technique is available through opt_params for pagination on newFetchAlbumsRequest and newFetchMediaItemsRequest.
We then added methods to create update, and delete albums and media items:
- opensocial.newCreateAlbumRequest(idSpec, album): Creates a new album and returns the ID of the album created. Containers implement restrictions - like allowing a viewer to create albums for only him/herself.
- opensocial.newCreateMediaItemRequest(idSpec, albumId, mediaItem): Creates a new media item in the album and returns the ID of the album created. Containers implement restrictions.
- opensocial.newUpdateAlbumRequest(idSpec, albumId, fields): Updates the fields specified in the params and returns void. The following fields cannot be set: MEDIA_ITEM_COUNT, OWNER_ID, ID. Containers implement restrictions.
- opensocial.newUpdateMediaItemRequest(idSpec, albumId, mediaItemId, fields):Updates the fields specified in the params and returns void. The following fields cannot be set: ID, CREATED, ALBUM_ID, FILE_SIZE, NUM_COMMENTS. Containers implement restrictions.
- opensocial.newDeleteAlbumRequest(idSpec, albumId): Deletes the album specified and returns void. Containers implement restriction.
- opensocial.newDeleteMediaItemRequest(idSpec, albumId, mediaItemId): Deletes the album specified and returns void. Containers implement restrictions.
Of course, the objects need values. We added an object and changed a few others. opensocial.Album makes its debut. The object has several fields:
- ID - string, unique identifier for the album
- THUMBNAIL_URL - string, URL to a thumbnail cover of the album
- CAPTION - string, the title of the album
- DESCRIPTION - string, description of the album
- LOCATION - opensocial.Address, location corresponding to the album
- OWNER_ID - string, ID of the owner of the album
- MEDIA_TYPE - array of MediaItem.TYPE, types of MediaItems in the Album
- MEDIA_ITEM_COUNT - integer, number of items in the album
opensocial.Activity.MediaItem was renamed to opensocial.MediaItem since it is no longer solely related to Activities. The MediaItem type earned a few new fields:
- ID - string, id Associated with the media item
- CAPTION - string describing the media item
- CREATED - string, creation time associated with the media item - assigned by container in UTC
- LAST_UPDATED - string, update time associated with the media item - assigned by container in UTC
- THUMBNAIL_URL - string, URL to a thumbnail image of the media item
- DESCRIPTION - string, description of the media item
- DURATION - integer, for audio/video clips - playtime length in seconds. set to -1/not defined if unknown
- LOCATION - opensocial.Address, location corresponding to the media item
- LANGUAGE - string, language associated with the media item in ISO 639-3 format
- ALBUM_ID - string, album to which the media item belongs
- FILE_SIZE - long, number of bytes (set to -1/undefined if unknown)
- START_TIME - string, for streaming/live content, time when the content is available
- RATING - integer, average rating of the media item on a scale of 0-10
- NUM_VOTES - integer, number of votes received for voting
- NUM_COMMENTS - integer, number of comments on the photo
- NUM_VIEWS - integer, number of views for the media item
RESTful API Changes
We added two new XRDS types: Albums and MediaItems. The RESTful API allows one to modify items in the container from external applications or through explicit XMLHttpRequests to the container. All responses from any request always come back wrapped by a Response object. These response objects have two different forms depending on whether or not the query returns a list or a single item. It is permissible for a single item to be returned in the list form. Example:
application/json representation:
{
"startIndex":1,
"itemsPerPage":10,
"totalResults":100,
"entry":[
//{...first item...},
//{...second item...},
//...
]
}
or, for only one item:
{
"startIndex" : 1
"itemsPerPage" : 10
"totalResults" : 100,
"entry" : {...only item...}
}
The XML representation is
<response>
<startIndex> 1 </startIndex>
<itemsPerPage>
10
</itemsPerPage>
<totalResults>
100
</totalResults>
<entry>...first item...</entry>
<entry>...second item...</entry>
...
</response>
Any responses coming back from the RESTful API will be wrapped as shown above. You can execute different HTTP verbs against the albums API and get different results. For example:
- A GET on /albums/@me/@self with yield an array of Albums
- A POST on /albums/@me/@self will create a new Album
- A GET on /albums/@me/@self/albumId with return only that specific album
- A PUT on /albums/@me/@self/albumId will update the album
- A DELETE on /albums/@me/@self/albumId will delete the album
The returned Album will be wrapped by the response shown earlier. Getting an album, you will see something like this:
application/json representation:
{
"id" : "44332211",
"thumbnailUrl" : "http://pages.example.org/albums/4433221-tn.png",
"caption" : "Example Album",
"description" : "This is an example album, and this text is an example description",
"location" : { "latitude": 0, "longitude": 0 },
"ownerId" : "example.org:55443322"
}
application/xml representation:
<album xmlns="http://ns.opensocial.org/2008/opensocial">
<id>44332211</id>
<thumbnailUrl>http://pages.example.org/albums/4433221-tn.png</thumbnailUrl>
<caption>Example Album</caption>
<description>This is an example album, and this text is an example description</description>
<location>
<latitude>0</latitude>
<longitude>0</longitude>
</location>
<ownerId>example.org:55443322</ownerId>
</album>
Once you have an album and its ID, you will want to retrieve its contents. The contents of the albums are MediaItems. Like the Album API, a different combination of HTTP verb and URL gives different results:
- A GET on /mediaitems/@me/@self/albumId with return the media items in the album
- A POST on /mediaitems/@me/@self/albumId can be used to create a new media item
- A GET on /mediaitems/@me/@self/albumId/mediaItemId will return the media item
- A PUT on /mediaitems/@me/@self/albumId/mediaItemId will update the media item
- A DELETE on /mediaitems/@me/@self/albumId/mediaItemId will delete the mediaItem
Each MediaItem will be wrapped in a response, looking something like this:
application/json representation:
{
"id" : "11223344",
"thumbnail_url" : "http://pages.example.org/images/11223344-tn.png",
"mime_type" : "image/png",
"type" : "image",
"url" : "http://pages.example.org/images/11223344.png",
"album_id" : "44332211"
}
application/xml representation:
<MediaItem xmlns="http://ns.opensocial.org/2008/opensocial">
<id>11223344</id>
<thumbnail_url>http://pages.example.org/images/11223344-tn.png</thumbnail_url>
<mimeType>image/png</mimeType>
<type>image</type>
<url>http://pages.example.org/images/11223344.png</url>
<albumId>44332211</albumId>
</MediaItem>
OK-- that's a lot to digest.
As always, if you want to join the discussion on OpenSocial and how it is evolving, please join the container developers (we need more application developers in this conversation!) at http://groups.google.com/group/opensocial-and-gadgets-spec?hl=en.