Navigation

Recent site activity


 

Overview of REST Implementation in Shindig - Java Version

Author Rajdeep Dua
Aug 2008

This article is based on Shindig code available in August ,2008 in svn

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.

xrds-simple

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

Explaination

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.

restfulcontainer

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

shindigRest

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.

detailedCompoents

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.

servletclassdiag

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.

dataserviceservlet

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.

getfriends1

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

getfriends3

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.

getfriends4

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

friends6

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

friends6

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

  1. 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
  2. Post
    • Create a new activity for guid identified by self
  3. 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.

createactivity1

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

createactivity4

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 

createactivity5

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

data_table

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.

getpersondata1

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

  1. http://www.opensocial.org
  2. http://code.google.com/apis/opensocial/
  3. http://incubator.apache.org/shindig/
  4. http://chrisschalk.com/shindig_docs/rajdeep/shindig-overview/onjava-shindig-overview-tidy.html
  5. http://rajdeep.dua.googlepages.com/shindigPHP-overview-tidy_img.html

 

Comments