4. Building a fully-featured, useful, and performant OpenSocial
application is a delicate balance, requiring deep knowledge of
Javascript, OAuth, REST, and a server-side framework.
Planning your architecture and view assembly patterns take time
& experimentation.
7. Develop in Firefox with Firebug
Of course you want your application to work well on all the major
browsers, but first you want an application that actually works, right?
The Firebug plugin for Firefox lets you inspect the final rendered
HTML of a gadget, the results of remote calls executed from
Javascript (like makeRequest, social data calls, etc.)
It does tend to slow execution time of a gadget considerably, but the
performance hit is worth it when you have so much information at
your fingerprints.
If you’re doing any Javascript programming or DOM manipulation in
your gadget, you need to use Firebug.
http://getfirebug.com/
8. Your JavaScript should never be naked.
Apart from functions and maybe setting up a few vars, any
Javascript you ever execute in an OpenSocial application should be
event-oriented.
Functions you want to execute on load should always be
wrapped in an OpenSocial onLoadHandler. You can specify as
many onLoadHandlers as you need, on a per-view basis.
This guarantees that the environment is ready for you before you
make calls.
gadgets.util.registerOnLoadHandler(initApplicaton);
Never dynamically insert or evaluate Javascript. This means no
<script> tags that dynamically load more <script> tags.
Never evaluate Javascript that you may have fetched remotely.
The entire universe of Javascript your application uses should be
referenced in your gadget spec.
Oh, and don’t use document.write.
9. Don’t go “whole hog”
Specify exactly the fields you want and need in social data requests.
Whether you’re requesting social data via Javascript or REST, always
enumerate the fields you want returned. This limits the amount of data
passing through the wire, allows container’s social data implementations
to choose the best strategy for data retrieval, and protects you against
nasty changes a container might throw at you like changing which fields
are returned by default.
No, this does not mean just ask for all fields.You don’t need them. Asking
for all fields is lazy & often seen as an indicator of abuse.
10. Your application should make liberal use of the views feature of OpenSocial. Don’t attempt to put
everything in a single <Content> block and rely on Javascript to control which content you display to
users.
Every view in an OpenSocial container is different. What’s appropriate for a Profile may not be
appropriate for a home page or a canvas view.
If an OpenSocial container supports sub-views, use them to further separate concerns in your canvas
views. For example, you could have a canvas.about view defined to tell users about your application, a
canvas.search view to present a search form, and a canvas.search_results view to present search results.
Sub-views make Data Pipelining easier also.
Don’t use AJAX and DOM manipulation exclusively to move between canvas contexts. This stops your
content from being bookmarkable.
If you have specific pieces of user-generated public content like a slide show, a document, or a profile,
you should consider using an ownerless canvas page (a LinkedIn-specific feature) and ensure that the
resource is available with a distinct re-usable URL.
Finally, don’t forget to always adjust the height of your modules after any DOM elements have changed
using gadgets.window.adjustHeight()!
Use Views
12. Consider Data Pipelining
Data Pipelining is the best way to prepare data you need before it even loads in
the browser. Use it to fetch social data from a container or from your remote
servers.
It works best for data that you always know you need in a view or subview, as
conditional logic is difficult to support with it.
Start by including it as a feature in your gadget spec.
13. Within your views, include script tags of the type text/os-data, containing data pipelining
directives in the form of an os-namespaced set of tags including os:ViewerRequest,
os:OwnerRequest, os:PeopleRequest for handling social data and os:HttpRequest for making signed
requests to your server.
Combine data pipelining with a good cache strategy and cut your application load latency
down dramatically.
Data Pipelining tags are feature rich and provide a more comprehensible codebase than a
chain of Javascript callbacks for data retrieval.
Each tag has a key attribute that you’ll use for retrieval in the next step.
14. Every pipelined request you labeled with a key is now available by retrieving a
dataSet from the dataContext.
If you’re working with JSON structured data, you can work directly with your
results.
Retrieving results from Data Pipelining is easy!
15. Say goodbye to a waterfall of callbacks.
()
ck
ba
all
k() cC ()
bas k
fu
ac allok
n
) k() ()
llb ksCBo () k(
cti
Ca Boo t ack ac
Ge ac
llb ack
on
ks Get onksCallb al)lb
)
n on Ca llb
ck(
oo C(
on
o
o
basck oks sCa
llba
tB nctio tBo
on
nG
sCa
cei allok
Ge fu
Ge fu onG t ksCBo k
()
o
ook tB oo
ack
e
on tion fun etBoo Get
t
tB
back() Callb
Ge tB
Bo nct
etB
on func ksCall
onG on nGe
oo
on
nG oks
cti
o i
etBoo
tion
no
ks on
on on o
k
n onG tBo
fun func
ctio
sC
cti cti ion
C
fun functio () Ge
all
allback ion on
fun fun unct
allb
opleC
b
ct
ac
f
n onPe
a
fun
ck
functio
() k
()
16. Data Pipelining has what you need.
• os:HttpRequests can re-use canvas parameters in requests.
• Pipelining tags are executed in sequence and can reference
data fetched by a previous tag
• os:HttpRequest has all the capabilities of
gadgets.io.makeRequest, including signed authorization
• People Resource tags support specifying specific fields and
building collections.
• Each dataSet object allows for error checking.
• Separating concerns with canvas subviews means that each of
your subviews can have their own Data Pipelining requests,
resulting in more efficient loading strategies.
But wait, there’s more!
17. Data Pipelining & OpenSocial Templates
Like star-crossed lovers, pipelining works best with templates.
18. OpenSocial templates mean even less code.
OSML templates are most often compiled server-side, binding the
results from Data Pipelining requests into placeholders within relevant
templates.
OSML allows for iterating over a collection and conditional logic within
a template using JUEL-like expressions, in addition to depending on the
existence (or absence!) of data.
Templates can exist inline within the gadget spec, or be loaded from an
external Template Library file.
To get started, include the opensocial-templates feature in your gadget
spec.
19. Suppose you requested some basic information on the OWNER of a
canvas page, like their name, thumbnailUrl, and profileUrl.
Additionally, suppose you retrieved information about a book in JSON
format from your servers based off a view parameter called bookId.You
expect results to contain a title, url, and thumbnailUrl.
Your Data Pipelining tags would look something like:
20. Now we’re going to write a OSML template that renders the book we
fetched from our server along with details about the owner of the
current canvas page.
Since we require a book & owner object to continue, we set a require
attribute on our tag equal to the comma-separated list of “keys” we are
need to render.
Our OSML tag to render a book with accompanying owner
information might look something like:
21. Assuming our data fetched correctly and was structured in the
expected format, our little OSML template should render like this:
23. Pre-production checklist
Before you put your application in front of potentially millions of users on an OpenSocial container,
there are still a few things you’ll want to make sure of.
Minification - While minified Javascript and CSS is a pain while you are in development, before you move to
production you want your Javascript and CSS to be as lean and minified as possible.
CDN - Consider hosting all of your static resources like Javascript, CSS, and images from a high-availability &
performant CDN provider.
Caching - Configure your web server or CDN provider to provide as much information about caching as
possible when serving static resources.You generally want to encourage a web browser to cache content for as
long as possible. Some OpenSocial containers even cache remote makeRequest calls, and they often will obey the
caching headers you provide. All those cache headers are great if they’re obeyed by a web browser, but you can’t
count on that. Add a query parameter to your Javascript and CSS src URLs with the current timestamp to help
cache bust stubborn browsers.
Profile Fields - Are you sure you aren’t being an information hog and asking for more social data than you
need? Explicitly declaring fields also protects you from future changes your OpenSocial container may make.
Versioning - Somewhere in the rendered HTML of your gadget you should have some kind of hidden HTML
content indicating which version of your gadget is loaded. This well save you a lot of time debugging if you aren’t
sure which version of your gadget the server has right now.
Performance - Can your servers handle serving out the dynamic content produced by the HTTP requests
your gadget makes to your home server? At what point would it break? Do you have a strategy for increasing
capacity on short notice?
24. OAuth
Seems like all APIs these days require some knowledge of OAuth. OpenSocial is no exception, though
it’s easier than you think.
Whenever you make a signed request from the container to your server, the request will be signed
using two-legged OAuth. Whenever you make a signed REST request to our container for social data,
you will also sign the request using two-legged OAuth.
In the case of LinkedIn, incoming requests to your server will be signed and you will validate the request
using a public certificate. When making API calls over REST, you will sign the request using your issued
consumer secret.
In two-legged OAuth, there is no concept of an access token or oauth_token parameter. When
representing a member while making REST requests, you specify an additional parameter called
xoauth_requestor_id with the value set to the member id of a user who has granted your application
permission.
The best way to validate requests is to use one of the OpenSocial client libraries developed by the
OpenSocial community and available at http://bit.ly/aJ44UG.
25. Parting words of advice.
Read OpenSocial API documentation voraciously.
Don’t be afraid to ask for help.
Experiment with different approaches while you are in
development. Once you’ve settled on an architecture, it’s difficult to
change. Building an OpenSocial application is also an opportunity to
build a rich API for your servers.
If you’re primarily primarily HTML from your servers, consider
wrapping the it in JSON hashes to provide your gadget metadata
that can assist you in assessing application state.
Use other OpenSocial applications as examples of what is possible,
especially if you can find a parallel to the type of application you are
building.
When designing the look & feel of your application, try to repeat
design patterns utilized by the container you will deploy to.
Don’t abuse virality options like activity streams & messaging. Each
viral event in your app should correspond to a direct user action.
It’s not interesting or valuable to a user’s connections that your app
was installed. It is interesting to discover what users are doing with
your application.