Shindig : An Architectural Overview ( PHP Version)

Author : Rajdeep Dua
June 08,2008

This article is based on Shindig PHP code available in svn in May 2008


Social Networking has taken the internet from read only mode to a real collaborative mode intertwined with human networks. This has opened up unlimited ways in which the information can be stored, retrieved and used. OpenSocial attempts to reduce the pain for application developers to write applications from scratch for various Social networking sites.

OpenSocial is a specification which envisions a write once, run anywhere mantra in the Social Networking space. Shindig is a reference implementation of OpenSocial specifications for developers to develop against container providers. The Shindig code base can be used as a starting point and modified for Social networking sites which want to join the OpenSocial revolution.

The goal of this open source project is to be language neutral and provide implementation in multiple languages. Currently Java and PHP implementations are available. In the previous article I had outlined the Architectural Components of the Java Version. Since a lot of Social Networking sites are based on PHP, Shindig's PHP version can be an option for them if they want their site to be a pure play PHP based site.

Shindig Components

Since the PHP version of Shindig has been ported from the Java Version, concepts like HTTP Servlet have been ported to a light weight HTTPServlet Implementation. The PHP version has a single entry point and all the calls are routed through index.php using Apache's mod_rewrite module.

Similar to the java version the PHP version also has 3 major server side components.

  1. Persistent Data Loading Mechanism
  2. Gadget Rendering Infrastructure
  3. OpenSocial server side implementation

Figure 1 describes these components in more detail. All the three components are accessed using HTTP / HTTPs through a Web Server. OpenSocial Server side components and Persistent Data Access Layer share a common Servlet Class ( GadgetDataServlet ), while Gadget Rendering components have a separate Servlet class as their entry point ( GadgetRenderingServlet).

Components of Shindig Server Side container

Figure 1 : Components of Shindig Server Side container

The container consists of 6 different servlet classes. We describe how each of these map to server side components listed above


Figure 2 : Class diagram of various servlets within the Shindig container

All the servlets are subclasses of HttpServlet and serve as independent entry points at runtime. This architecture adoption has to do with the way in which Shindig has evolved.

Home page of the SampleContainer

The home page of the Sample container - samplecontainer.html is loaded by the FilesServlet class and served to the browser .Figure 3 below explains the sequence on how this loaded using mod_rewrite rerouting all the requests to Index.php. This page has gadget container and rpc JavaScript code embedded and servers as the starting point of all the calls to the Shindig server. For the social networking sites planning to embed shindig these javascript files will become part of their pages where gadgets are going to be rendered.

Load SampleContainer.html

Figure 3 : Sequence diagram explaining how the SampleContainer.html is loaded by the FilesServlet.php

Persistent Data Loading Mechanism

This layer is responsible for loading the persistent social data which includes- Person details, friends list, activities associated with a Person. In the default implementation this is stored in an XML file.

The GadgetDataServlet provides the entry point for the Persistent loading mechanism. This layer is pretty much pluggable and can be easily replaced with a more robust persistence mechanism. OpenSocialData Handler is used to populate the OpenSocial objects and query them. OpensocialDataHandler knows which handlers to invoke for loading the data from the XML file. The type of handler invoked depends on the kind of request.

Gadget Rendering Infrastructure

Gadget Rendering infrastructure has client side and server side components. It is responsible for generation of Gadget HTML from the Gadget Xml.

Client Side Components

gadget.js --> JavaScript library which calls the GadgetRenderingServlet.

Server Side Components :

  1. GadgetRenderingServlet
  2. GadgetServer
  3. GadgetSpecParser
  4. HTTPFetcher
  5. Gadget

Diagram below explains the sequence in more detail on how HTML is generated from the Gadget Xml and sent back to the browser.


Figure 4 : Collaboration flow on how the Gadget XML gets converted into HTML by the GadgetRenderingServlet and its downstream components

OpenSocial Server Side Implementation

We will be covering this scenario in more detail using the collaboration diagram. This diagram will show the call flow from the client side to the server side.

Client Side Components:

All the javascript calls to the server are made either through the GadgetContainer or the OpenSocial Container on the client side. Figure 6 depicts the APIs and client side container interaction.


Figure 5 : Client Side Java Script Objects and their interaction.

Shindig supports the following OpenSocial features for the 0.7 version .The javascript files for these features are available in Shindig in the directory <root>/features

  1. open-social-0.7
  2. opensocial-reference

All the Java script files within these are added to the generated HTML.

Figure 6 provides the details of various classes which represent and store the social graph on the client side for OpenSocial APIs.


Figure 6 : OpenSocial Model Class diagram

Server Side Components

All the OpenSocial calls are received by GadgetDataServlet and passed on to an instance of OpenSocialDataHandler. The actual type of data handler called depends on the type of request. List below is representative of the types for OpenSocial APIs.

In the PHP implementation, OpenSocialDataHandler is responsible for handling all the requests. Figure 6a shows the Class diagram and Object composition which is involved in loading data for Person, Activities and Persistence from the Xml file


Figure 6a : Class and Object composition diagram for handlers responsible for loading and persisting social graph and related data in the Xml file.

GadgetDataServlet holds an array of handlers and has the mapping for which handler to call based on the nature of the call. In PHP implementation OpenSocialDataHandler is the only handler through which the flow goes. It extends the GadgetDataHandler and holds object instances of BasicPeopleService, BasicActivitiesService and BasicDataService.All the three services extend the corresponding abstract classes and are part of the SampleContainer. BasicPeopleService, BasicActivitiesService and BasicDataService eachof these classes use a single instance of XmlStateFileFetcher to parse and load data from the xml state file.

We will take FETCH_PEOPLE as an example and go through the flow in the figure below. BasicPeopleService is a wrapper on XML file based Persistent store which is used in Shindig .( XML file based implementation is just for demonstration, needs to be replaced by a more robust persistent mechanism)

This service loads, parses and stores the data of Person, Friends, Activities in memory in arrays in PHP (it was Maps in the Java version). Depending on the nature of call data is retrieved in memory, converted into JSON object(18) and sent back (19,20,21 ) to the client side for presentation.




Figure 7 : Collaboration diagram tracing call to view friends from client side javascript to server side components and back


Replacing the default Sample Container persistent store with a Custom Store

The diagram below expands the discussion so far into one figure. The OpenSocial Sample Container piece is the actual runtime by default. It consists of 3 services, BasicPeopleService, BasicActivitiesService and BasicDataService.


Detailed Architecture

Figure 8 : Shindig architecture components and Sample Container Implementation


For Custom Persistent implementation the following classes in Figure 10 need to be replaced and implemented according to the storage mechanism being put in place. The handler class name also needs to be configured in config.php. For example, if we have a customer handler with a name 'MyHandler', the configuration will be 'handlers' => 'MyHandler'. There are other classes which can be easily replaced like Gadget blacklist , remote content fetcher and caching mechanism. Containers might want to modify or have their own custom implementation.

Sample Container Files


Shindig's basic implementation is a good starting point for somebody interested in getting started quickly on OpenSocial in their networking web sites. We explained how the container has a single entry point implemented using index.php and mod_rewrite module in Apache. The actual implementation is a straight port of servlet concept from the Java world with a basic Http servlet as a starting point. The rendering and social data access are independent components and can be replaced depending on the needs for it has to be used. Towards end of the article we talk about the pluggable nature of the data persistent layer. The pluggability in the architecture is a big help in adapting it quickly to the exact storage model required to be plugged in.

Shindig itself is a moving target with an active community and OpenSocial's evolving spec,but is a very good starting point for container providers looking for a head start.

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.