16 Nov, 2007
Posted by Bhavin Turakhia
This is part 3 of a 3 part article on Building Platforms vs Building Applications. Refer the below index to review the other two parts. It is recommended that you read them in order – Part 1, Part 2 and Part 3.
- PART I – Advantages of building a Platform
- PART II – How to go about building a Platform – Techniques and Concepts
- PART III – Principles to keep in mind when designing a Platform
This third part cover certain Principles to keep in mind when designing and deploying your platform. These are -
Abstraction and Loose coupling are your friends – always go n-tier
Design your software as an n-tier application. Ensure the data layer, the business logic layer and the UI layer are loosely coupled. Infact even within the business logic layer, there is opportunity to loosely couple or layer various functionality such as authentication, provisioning and so on. The more loosely coupled your architecture, the greater the possibility of providing hooks and APIs for extensibility.
Think of yourself as your own client
One easy way that I have used to get around to designing extensible applications, is to begin thinking of myself as my own client. What this means is that I divide my application into various modules, and then assume each module is being developed by a separate entity.
For instance, one can assume that separate entities are building your user interfaces and core libraries. This way not only does your design starts out as being loosely coupled but also you begin thinking from the perspective of a third party vendor. Since you will be the first consumer of your own platform, you will be able to think of the design and any pitfalls during initial development.
Identify the core foundation of your platform and build the rest as plugins
Each application has a core set of functions or core purpose. Identify this for your application. Clearly document / outline it. Then build the rest of your application as plugins that hook into the core. This is actually a very interesting way of designing an application, where your application is divided into multiple independent applications all of which plugin to or hook into the core. Infact, all successful platforms are invariably designed in this manner to start with.
Operating Systems (which in some sense are the most successful platforms) have always been designed this way. The core OS provides device access and a process space to run applications. All other features, whether bundled with the OS or installed separately, built by the same vendor or by a third party, access this core platform. Microsoft would have never gained any traction, if their OS and all bundled applications were built as a monolithic application. By separating the core OS functions from the user applications, they created a platform rather than a monolithic software.
Atlassian’s Confluence is another application that has achieved this brilliantly. At the core of their platform is a content management system, revision control system and permission management system. Everything else, all their user interfaces, including their admin interfaces hook into this core as plugins. This has resulted in a robust plugin framework that external entities can use in the same manner as atlassian, leading to a large library of plugins contributed by third party coders Facebook is a more recent example. Many of facebooks own features and applications are built as plugins to their core platform. Their core platform provides a social network, a set of privacy definitions, and a publisher-subscriber model for events. Many of their features layer on top of these core libraries, which they have now exposed through their Developer Network, enabling others to build identical extensions.
Update: If you want to take this principle one step further, then another way of breaking down your application is to have NO CORE. Think of all parts of your application as loosely coupled components of equal importance.
Leverage / Create easy-to-implement protocols – HTTP is your best friend
Noone wants to write to a CORBA API or a custom binary protocol . While most applications will go the HTTP / SOAP / REST route without thinking twice, this is still an important element. Make your APIs as easy to understand and implement as possible. Use standard easy-to-use protocols. Ensure that the method signatures / interfaces are self explanatory. The easier it is to implement your API, the more momentum your platform will gain.
Componentize / Widgetify your UI
Do not build single, hard-coded monolithic User Interfaces. While the OOPs paradigm has taught us to think of our core code in the form of modular classes and methods, there unfortunately is no such paradigm for Web UI. Desktop UI does follow a component model to a large degree. When building a desktop app, users are forced to think of controls and components. But when designing web applications, most developers unfortunately treat a page as a unit. It is important to begin thinking of a page as a container of independent widgets. Design your Web UI such that there are no inter-dependencies between multiple controls on a single page.
Build an event driven architecture
Every application has events which result in actions. Instead of hardcoding these as a linear procedural piece of code, you can choose to build or use existing event-driven models. Wherever you find events and actions within your applications, you can build event listeners, event queues and event handlers
Build an easy discovery/installation/update mechanism for extensions / plugins
So far I have spoken about how you need to make it easy for a developer to build extensions. Another important element is how easy is it for a customer to begin using those extensions. You may have a brilliant platform, but if your users cannot find the extensions or need a phd in compsci to install them, you will not achieve any success. The two elements to keep in mind are discovery and ease of installation/updation.
Once again, at the risk of sounding like I have an agenda with them, Atlassian does a very good job of this. They have an extensive online wiki which categorizes all their plugins and extensions for Confluence and JIRA. Each extension also has its own page, containing all the relevant information about that plugin, its installation, usage etc. All-in-all it is quite well organized. Now if that wasnt enough, recently they began bundling their Confluence Repository Client within their product. So now the entire plugin directory is available from within the Admin interface of their product. This means any user who uses confluence can discover and directly install all plugins from within the application itself. This makes both the discovery and the installation/updation process fairly easy. I think this is a great strategy – ie to bundle an interface which allows plugin discovery and installation within the primary application itself. Interestingly, the interface (the Confluence Repository Client) that manages this within Confluence, is itself an extension .
Noone however has done this better than facebook. They have not only built an very intuitive interface for installation/uninstallation/updation of plugins (point and click) – but they have linked discovery to their social network. Each user is notified about the plugins installed by their friends, creating a unparalleled viral effect, and a never-before implemented discovery model.
While it may not be possible in all applications, try and keep the process of plugin installation as simple as possible. The lesser the friction the faster the adoption. For instance a desktop app plugin which requires superuser privileges to install, has additional friction in comparison with one that doesnt.
Design a future-proof database / datastore
A sure-fire way to reverse the success of your platform is to ignore backward compatibility. The worst thing you can do, is enable third party vendors to develop plugins / extensions for your platform, and then make changes to your platform that render their extensions incompatible.
One of the common reasons for changes in an API is a poorly thought out data structure. All applications consist of code that manipulates data. Typically this information and metadata is stored in an RDBMS or other data stores. When adding new features, one needs to add new columns / attributes to an existing data definition. If the database structure was not created anticipating such future additions, then an upgrade may require a drastic change to the data model. This change in turn impacts multiple areas of the platform and its APIs.
It is important to consider a long term roadmap of your application when designing your database structure. Try and design the database in a manner that future feature additions do not impact the data structure drastically. Some other situation-specific tips are – do not try and put everything into one table, or even one database. If you build your application out such that everything is in a single monolithic linked data structure, a single change will have multiple repercussions. Many a times when using RDBMses developers are motivated to do just that to obtain referential integrity advantages even when they are not needed. IMHO Referential integrity is quite over-rated.
Build a robust Security and User Privacy model
Think through what type of access do you want to provide to a third party extensions / plugin. Design a security framework which provides various levels of access which can be controlled by you and/or the user. For instance, facebook allows a user to control what information a facebook application can access of that user. Security and User Privacy are two separate elements. While user privacy controls, define the information of a user that can be accessed by an extension, Security refers to ensuring that a plugin / extension / 3rd-party application does not obtain unauthorized access to any information, does not performs any unauthorized action, and does not compromise the security of the platform in any manner.
Take good care of your third party developer network
The success of a platform is directly proportional to the developer momentum you can create. Many successful companies go to great lengths when it comes to taking care of their third party developer network. Here are a few ideas -
- Provide detailed clear documentation. One good way of doing this is to host it on a wiki whereby the community can contribute to it. The wiki can bemoderated to prevent abuse. Your documentation should contain an implementation guide, API reference, error guide, downloadable example scripts, tutorials, videos, testing tools etc.
- Provide a sandbox environment to facilitate testing. The sandbox environment should be identical to the live environment. Developers should be able to create multiple sandbox accounts. Developers should have the capability of resetting the sandbox environment
- Many companies provide developers with additional assistance such as a free hosting environment, a dedicated bug tracker, an SVN or CVS code repository
- Organize workshops, roadshows and geek-fests for your developer following. Give them opportunity to gain recognition within peer groups and collaborate with one another face-to-face.
- Give them access to talk to and connect with your tech team, through forums / structured chats and in any other manner possible
This sums up a basic list of principles you should keep in mind when designing a platform. While I have attempted to pen down as many elements as I could think of, you need to keep in mind when designing a platform, nothing beats practical training. I would strongly reccommend checking out Facebook, Confluence, Ning, Salesforce and other such existing platforms, their implementations, APIs, documentation, strategies etc.
Click on any of the links below to read the other two parts of this 3 part post -