Sunday, June 6, 2010

Facebook Graph API – A First Look

Trying the Facebook Graph API in a Browser
The Facebook Graph API is for developers who want to integrate with Facebook and read and write data from Facebook. (The docs are here – sometimes it makes me sign in to see the doc!?) What you need to know to start is that “graph” really means a “social graph”. For example, a user’s social graph includes all the things important to a user like people, photos, friends, and shared content. Data in a social graph falls into two categories: objects (like people, photos, and events) and connections between objects (like relationships, shared content, and tags). When you work with the Graph API you’ll be working with objects and connections.

The “normal” way to use the Graph API is to get an application ID (here) that represents your company or application. Then, on a page of your web site you set up the infrastructure using one of the APIs (e.g. the JavaScript API) so that when a user comes to your page, hits the Facebook login button, and authorizes your web site to access data, the Graph API would be used behind the scenes. In a future post I'll cover that.

You can start getting familiar with the Graph API without an application ID by just constructing Graph API requests directly in a URL. Note, that Chrome and Firefox browsers display the JSON results of these requests directly in the browser which is nice. If you put the URL above in the address bar of Internet Explorer it will ask you want to do. You can download it somewhere, name it .txt and view it. Just more work.

If you put this URL ( for the founder of Facebook, Mark Zuckerberg, into the address bar of Chrome you get the publicly available data for his page (an object). The “?metadata=1” part of the URL requests that connection information for the object be shown. The results of the Graph request above will give additional Graph requests you can follow and drill down into the data. So for example, take Mark Zuckerberg’s photos link ( and put that in the browser address line and so on.

This is what I started doing at first for myself and friends - Graph requests in a browser - to see how it worked. Then, I wanted to automatically check all the links without doing so much cutting and pasting and that’s where the code shown below comes in play. I created a first version and then found this page ( and created a second page with some of the good ideas I found there. I wanted to play around with jQuery and issuing Ajax requests from the page so that drove the design of my page. My page checks all the connection links and displays the results (what was found) in the page. The previously mentioned link ( is a simpler and slicker page in that it’s just based on navigating to URLs.
Using the Graph API to Look at a Page
Drill Down on Feed
Using the Graph API to Drill Down to Feed
Graph API Looking at a User's Info

A Javascript Program To Work With Facebook API
The code below uses the ajax method of jQuery to get data from the Facebook Graph API. No data is written back. A big gotcha is that I could only run this code successfully in Internet Explorer. In Chrome or Firefox, it was a no go. I didn’t troubleshoot enough to find out why, though I saw others had problems with the ajax method in these browsers. I’ll revisit the issue.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="">
<title>Using the Facebook Graph API</title>
<script src="" type="text/javascript"></script>
<script type="text/javascript">
var baseUrl = "";
var pageUrl = window.location.protocol + "//" + window.location.hostname + window.location.pathname;
var notDef = "Not Defined";
$(document).ready(function () {
$('#Go').click(function () {
window.location.href = pageUrl + "?check=" + $('#Input').val();
if ("check") > -1) {
var params ="=");
function checkGraphAPI(itemToCheck) {
url: baseUrl + itemToCheck + '?metadata=1',
async: false,
data: null,
dataType: 'json',
success: function (data) {
bShowOnlyVisible = $('#ShowFlag').attr('checked');
processObjectResults(data, 0, "object");
error: function (xhr, ajaxOptions, thrownError) {
$('#Output').html("Can't load anything. Could be invalid Graph API request.");

function processObjectResults(data, level, idFrag) {
if (data !== null) {
var objKeys = [];
for (var objKey in data) {
// Get object properties.
for (var i = 0; i < objKeys.length; i++) {
var property = data[objKeys[i]];
if (property === undefined || property === null) {
createOutputElement(objKeys[i], notDef, "Good", "child", level, idFrag + objKeys[i]);
else {
if (property.constructor === Object || property.constructor === Array) {
createOutputElement(objKeys[i], "", "", "openparent", level, idFrag + objKeys[i]);
processObjectResults(property, 1, objKeys[i]);
createOutputElement("", "", "", "closeparent", level, idFrag + objKeys[i]);
else {
createOutputElement(objKeys[i], property, "Norm", "child", level, idFrag + objKeys[i]);
else {
$('#Output').append("Couldn't look up the object. Could be permissions related.");
function processConnectionResults(data) {
if (data !== null) {
// Get connection properties.
var connections = data.metadata.connections;
var connKeys = [];
for (var connKey in connections) {
for (var j = 0; j < connKeys.length; j++) {
var conn = connections[connKeys[j]];
doConnectionCheck(conn, "connections" + connKeys[j]);
else {
$('#Output').append("Couldn't look up the connections. Could be permissions related.");
function doConnectionCheck(url, elem) {
url: url,
async: true,
context: $('#' + elem),
dataType: "json",
success: function (response) {
if (response !== null) {
if ( {
if (( === 0) {
$(this).append(" - No Data Found");
else {
$(this).append(" - Visible");
else {
$(this).append(" - Unknown");
error: function (xhr, ajaxOptions, thrownError) {
var errMsg = "Error Viewing." + " Found: " + xhr.status + ", " + xhr.statusText;
$(this).append(" - " + errMsg);
function createOutputElement(prop, text, style, type, level, id) {
var div1 = document.createElement("<div>");
var div2 = document.createElement("<div>"); = 120 + parseInt(level) * 30; = id; // where the results go
div1.className = "Prop";
div2.className = style;
switch (type) {
case "child":
div1.innerHTML = prop + " = ";
var link = text;
if (text.toString().indexOf(baseUrl) > -1) {
link = text.split(baseUrl)[1];
if (text !== notDef) {
if (prop === "picture" || prop === "icon") {
var img = document.createElement("<img/>");
img.src = text;
div2.innerHTML = img.outerHTML;
else {
div2.innerHTML = createHyperlink(link) + " ";
else {
div2.innerHTML = text + " ";
case "openparent":
div1.innerHTML = prop + " { ";
case "closeparent":
div1.innerHTML = " } ";
$('#Output').append(div1.outerHTML + div2.outerHTML);
function createHyperlink(link) {
var a = document.createElement("<a>");
a.href = pageUrl + "?check=" + link;
// = "_blank";
a.innerHTML = link;
return a.outerHTML;
<style type="text/css">
body { font-family: Verdana;}
div { float: left;}
div.Prop { width:120px; text-align: right; clear: left;}
div.Bad {color: Red; font-weight: bold; }
div.Good {color: Green; font-weight: normal; }
div.Norm {color: Black; }
Using the Facebook Graph API </h3>
Put in the ID or Friendly Name of a Facebook user in the text box below and then
hit go. For example you could enter "markzuckerberg" or his id "68310606562". To
find an ID of Friendly Name right click and view properties of the person/group/product
link in Facebook. This test does not require a Facebook account or to be logged into Facebook.
<br />
<input type="text" id="Input" value="" />
<input type="button" id="Go" value="Go" />
<br />
<span id="Output" ></span>


  1. Don't worry, I checked you out with the Graph API, you are 'exposed'.