Introduction
In the previous articles[1] we have discussed about Shindig architecture on the Java side in detail, focusing on tech class diagrams as well as runtime collaboration diagrams. In this article we focus on the REST implementation which has been added since the last article. REST based implementation has various components, in this article we will be focusing on the Read only operation (GET)within the REST spec as other pieces ( POST, PUT, DELETE ) which modify the state still have to be implemented.
In this article we will be focusing on the key runtime components which serve the REST API calls. Detailed flow discussions will focus on the GET calls as the POST, PUT,DELETE calls have still not been implemented the Java Shindig.
REST Architectural Style
REST as we know stands for Representation State Transfer and was a term coined by Fielding as a part of this PhD thesis as one of the architectural style. Key aspects of this style
- Resources : Application state and features represented as resources with unique globally idenfiable addresses ( URLs )
- Operations : Constrained set of Operations
- Statelessness : System by default does not maintain state between the calls.
- Content - Type : Predefined constrained set of content type.
World wide web is a form of REST Architectural style with the following mapping
- Resources : Web pages
- Operations : GET, POST, PUT, DELETE - as supported by HTTP 1.1
- Content : HTML, XML, JSON,
OpenSocial REST Specification
OpenSocial foundation realized the inherent benefits of REST and have released specification specifying the resources and the unique URLs which will define the address for these resources.
Discovery of the resources
OpenSocial relies on XRDS simple specification for discovery and defining the meta around resources. XRDS Simple is a subset or original XRI 1.0 specification providing simpler means for defining the resources and their metadata at the same time being fully compliant XRI 2.0 specification.

Figure 1 : XRDS Simple document defining the REST Service endpoints in terms of Type and URI:Template
Figure 1 provides the tree representation of the XRDS document and what various nodes mean in relation to the OpenSocial REST endpoints.There are four types of REST services which can be exposed by an OpenSocial containers - People, Activities, Appdata and Group.There are URI Templates defined for each type of service.
Type
|
URI-Template
|
|
People
|
1./people/{guid}/@all
2./people/{guid}/@friends
3./people/{guid}/{groupid}
4./people/{guid}/@all/{pid}
5./people/{guid}/@self
6./people/@me/@self
|
1.Collection of all people connected
to user {guid}
2.Collection of all friends of user {guid};
subset of @all
3.Collection of all people connected to user
{guid} in group {groupid}
4.Individual person record for a specific
person known to {guid};
shows {guid}'s view of {pid}.
5.Profile record for user {guid}
6.Profile record for requestor
|
Activities
|
1./activities/{guid}/@self
2./activities/{guid}/@friends
3./activities/{guid}/{groupid}
4./activities/{guid}/@self/{activityid}
|
1.Collection of activities generated by given
user
2.Collection of activities for friends of the
given user {guid}
3.Collection of activities for people in group
{groupid} belonging to given user {uid}
4.Individual activity resource; usually discovered
from collection
|
Appdata
|
1./appdata/{guid}/@self/{appid}
2./appdata/{guid}/@friends/{appid}
3./appdata/{guid}/@self/{appid}?fields=count
|
1.All app data for user {guid}, app {appid}
2.All app data for friends of user {guid} and
app {appid}; read-only (only GET and HEAD
supported)
3.Just the count field for user {guid}, app {appid}
|
Group
|
/groups/{guid}
|
Collection of groups associated with user {guid}
|
Table 1 : Source - REST API spec
REST Implementation in the client side container
Shindig Client side has a Restful container which extends OpenSocial container and is the component which passes on all the OpenSocial API calls to the REST endpoints. This means that the Endpoints serve both direct HTTP calls as well as calls from the OpenSocial APIs. Restful Container uses gadget.io package which opens an XmlHttpRequest object and then sends the data to the server.

Figure 1.1 : Restful Client container to make Client calls to REST Endpoints for OpenSocial Javascript APIs
REST Implementation in the Server side container
DataServiceServlet is the new Servlet added to support REST Endpoints. It along with the downstream components constitute the basic infrastructure on the which the REST APIs have been built. We had discussed in the earlier articles on various components within Shindig Java implementation, DataServiceServlet is another entry point in addition to the earlier components we had talked about -- GadgetRending and Data
Figure 2 : DataServiceServlet -- Entry point for REST Endpoints
Next Figure expands the blocks in more detail on how they interact with the handlers and the persistent state.

Figure 3 : Detailed component diagram of Rest implementation in Shindig
Diagram below provides the snapshot of the DataServiceServlet and its relation with other servlets. DataServiceServlet extends InjectedServlet and receives all the requests coming to Rest Endpoints.

Figure 4 : Servlet class diagram representing the class hierarchy of various entry points into Shindig
DataServiceServlet holds the reference of all the Handlers : People, Activity and AppData as well as the Bean and JsonConvertors. Class diagram below describes the relationship in more detail.

Figure 5 : DataServiceServlet's Object composition diagram showing the Handlers and Converters used by it to handle the REST calls
Handlers and Convertors.
All the REST calls are handled by one of the three handlers : PeopleHandler, ActivityHandler and AppDataHandler. All three of them extend DataHandler and hold reference to the JsonDBService which implements all the three interfaces : People, Activity and AppDataService. Convertors on the other hand are responsible for serializing objects into either Atom or Json depending on the format specified in the Url. Both these convertors implement BeanConvertor.
People based Scenarios
Rest Endpoint is identified by /people/ keyword all the sub URLs target Person and People specific scenarios. This endpoint supports getting the information , updating person specific information or deleting the information.
- Get
- Information of all the people belonging to any group
- URL : http://localhost:8080/social/rest/people/john.doe/@all
- Results :
- Information of all the profiles directly linked with the person identified by guid
- URL : http://localhost:8080/social/rest/people/john.doe/@friends
- Information of all the people linked with a Person identfied by guid and belonging to a groupId
- URL : http://localhost:8080/social/rest/people/john.doe/{groupid}
We will explain in a step by step process the GET call to get all the friends of a person using REST. Diagrams below gives a high level flow.All these flows are for http://localhost:8080/social/rest/people/john.doe/@friends?st=a:a:a:a:a:a.

Figure 6 : Describes the overall sequence for the GET Rest call for getting all the friends of john.doe
a:Calls the service method of DataServiceServlet
b:Calls the doPost method
b.i :Calls the getSecurityToken(..) method,
b.ii :Gets the Convertor for the request
b.iii :handleSingleRequest(.) method to handle the
single request
|

Figure 7 : Details out step b.ii in Figure 6 in more detail
b.ii.a : Gets the value of the 'param" url parameter from
the servletRequest object
b.ii.b : Gets the appropriate Convertor , if param=null
get BeanJsonConverter else if the parameter is
'atom' returns BeanXmlConverter.
|

Figure 8 : Details out step b.iii in more detail
b.iii.a :get the http method from the parameter
b.iii.b :Create a RequestItem Object
b.iii.c :HandleRequestItem
b.iii.c.1 :Gets the route from the parameter
b.iii.c.2 :Gets the Handler from the InjectorImpl,
PersonHandler in this case
b.iii.c.2.1 :returns PersonHandler
b.iii.c.3 : finally call the handleItem using this
RequestItem
|

Figure 9 Shows the details of fist step in handleitem(requestItem) method
b.iii.c.3
b.iii.c.3 : handleItem(requestItem)
b.iii.c.3.1 :calls the handleGet in PeopleHandler for
the following patterns
/people/john.doe/@all
/people/john.doe/@friends
/people/john.dpe/@self
b.iii.c.3.1a: parses the Url template to get userId
and groupId
|

Figure 10 : Expands the getPeople(..) request to get the JSON string
to be send back to the client
b.iii.c.3.2 :Call getPeople method in
JsonDbOpenSocialService
b.iii.c.3.2.a :Get JSONObject which holds the social
graph
b.iii.c.3.2.b :Get the Ids of friends for the userid
b.iii.c.3.2.b.1 :Get the JSONObject from the
FRIEND_LINK_TABLE
b.iii.c.3.2.c :Create and populate JSONArray ( people )
and populate it based on return object
form
the previous call.
b.iii.c.3.2.d :Convert the JSONArray into string and
send it to the print writer.
|
Activity based Scenarios
Activity based Scenarios supported by REST Endpoints are
- Get
- Get activities for the self
- Get activities for friends
- Get activities for a particular group specified by groupId
- Get details of a particular activity
- Post
- Create a new activity for guid identified by self
- Delete
- Delete an activity identified by guid.
We will call a simple POST end point for creating a new Activity. We will hit the following endpoint and trace the flow of calls in the server side. http://localhost:8080/social/rest/activities/john.doe/@self?st=a:a:a:a:a:a. The content-type for POST request is application/json with character set of UTF-8.
Figure 11 : Describes the overall sequence for the POST Rest call for updating activity stream of john.doe. Almost same as Figure 6 -- Except POST instead of GET
a:Calls the service method of DataServiceServlet
b:Calls the doPost method
b.i :Calls the getSecurityToken(..) method,
b.ii :Gets the Convertor for the request
b.iii :handleSingleRequest(.) method to handle the
single request
|
Figure 12 : Details out step b.ii in Figure 11 in more detail Almost same as Figure 7 -- Except POST instead of GET
b.ii.a : Gets the value of the 'param" url parameter from
the servletRequest object
b.ii.b : Gets the appropriate Convertor , if param=null
get BeanJsonConverter else if the parameter is
'atom' returns BeanXmlConverter.
|

Figure 13 : Details out step b.iii in more detail
b.iii.a :get the http method from the parameter which
is POST in this case
b.iii.b :Create a RequestItem Object
b.iii.c :HandleRequestItem
b.iii.c.1 :Gets the route from the parameter
b.iii.c.2 :Gets the Handler from the InjectorImpl,
ActivityHandler in this case
b.iii.c.2.1 :returns ActivitynHandler
b.iii.c.3 : finally call the handleItem using this
RequestItem
|

Figure 14 Shows the details of fist step in handleitem(requestItem) method
b.iii.c.3
b.iii.c.3 : handleItem(requestItem)
b.iii.c.3.1 :calls the handlePost in ActivityeHandler
for the following patterns
/activities/john.doe/@self
b.iii.c.3.1a: parses the Url template to get userId
and groupId ,userId is John.doe and
groupId is @self
|

Figure 15 : Expands the createActivity(..) request.
to be send back to the client
b.iii.c.3.2 :Call createActivity method in
JsonDbOpenSocialService
b.iii.c.3.2.1 :Create a JSONObject from the parameters
for creating an activity object.
b.iii.c.3.2.2 :Get the JSONObject from the
ACTIVITIES_TABLE
b.iii.c.3.2.3 :Update the ACTIVITIES_TABLE with the
new activity object
|
AppData based Scenarios
AppData are key values pairs stored for each application. The data is passed on to the server either in the JSON or the Atom format. This data can be either for a single entry or a batch of entries together. Key scenarios covered as a part of AppData from a REST Endpoint are
- GET AppData for an IdSpec ( userid , groupId @self or @friends } and keys specified as Array or '*' to get value of all the keys for a particular person
|

Figure 16 : Persistent AppData Storage format
|
- Example 1 :
- Request URL : http://localhost:8080/social/rest/appdata/john.doe/@self/@app?count&st=a:a:a:a:a:a
- Response : {"entry":{"john.doe":{"count":"0"}}}
- PUT, POST update AppData for a user identified by a userId with key value pairs
- Key, value pairs specifying the AppData value to be stored
- Delete AppData for a particular person specified by PersonId and keys of the appdata specified.

Figure 17 : Collaboration diagram showing the server side object interaction to get app data for a particular user and app data key, describes the key components of AppData and how they interact with each other to serve the REST requests coming through DataServiceServlet.
a:Calls the service method of DataServiceServlet
b:Calls the doPost method
b.i :Calls the getSecurityToken(..) method,
b.ii :Gets the Convertor for the request
b.iii :handleSingleRequest(.) method to handle
the single request
b.iii.c.1 :Gets the route from the parameter
b.iii.c.2 :Gets the Handler from the InjectorImpl,
AppDataHandler in this case
b.iii.c.3 : finally call the handleItem using this
RequestItem
b.iii.c.3.2.a : Get the Data_table for the userId
b.iii.c.3.2.b : Create a PersonData JSONObject
from the data extracted in step (a)
b.iii.c.3.2.c : Create person to app data map
b.iii.c.3.2.d : Create ResponseItem and send it to
the browser
|
Summary
In this paper we covered where the REST implementation fits in Shindig - OpenSocial's reference implementation. REST has both client and server implementation as normal OpenSocial API calls also go through REST endpoints. We covered REST calls for Person/People , Activities and AppData related Scenarios. We also covered the discovery aspect of REST endpoints which uses XRDS Simple specification.
About the Author
Rajdeep is with Google Developer API Evangelism team working on OpenSocial Advocacy. He has around 10 years of experience in middleware, webservices and Integration space. Before joining Google he was leading development effort for CSF: Connected Services Framework Initiative in Microsoft India. He has also contributed to JBoss Open source development in the past. Rajdeep holds an MBA from IIM Lucknow, India.
References
- http://www.opensocial.org
- http://code.google.com/apis/opensocial/
- http://incubator.apache.org/shindig/
- http://chrisschalk.com/shindig_docs/rajdeep/shindig-overview/onjava-shindig-overview-tidy.html
- http://rajdeep.dua.googlepages.com/shindigPHP-overview-tidy_img.html