Relationship Status with FQL: It’s Complicated


FQL blog post illustration 1-01

FQL stands for Facebook Query Language, it is just one part of the Facebook API. Before we jump right in to FQL, let me give you a little history. FQL is basically Facebook Graph API’s older brother. It is more mature, doesn’t make quite as many mistakes, and can walk and chew gum at the same time (perform multiple tasks simultaneously). FQL enables a SQL-esque interaction with the data that the Graph API holds. In my experience, I have yet to come across another API that is formatted this way, and although the Facebook API is generally unstable, FQL is still one of my favorites to interact with.


Just as you would query a SQL database table, you can query FQL tables. The table reference guide can be found here. So let’s write a basic query to get the logged in user’s name, profile picture, and email address. Our query ends up looking like this: SELECT name, pic_square, email FROM user WHERE uid = me(). You can pass me() to the uid to let FQL know you would like the logged in users information. Otherwise, you could pass a users facebook id. So this seems a lot like querying a SQL database and not pulling from an API right? So lets add in the PHP code to run the query.

  $app_id = 'YOUR_APP_ID';
  $app_secret = 'YOUR_APP_SECRET';
  $my_url = 'POST_AUTH_URL';
  $code = $_REQUEST["code"];
  // auth user
  if (empty($code)){
    $dialog_url = '
       client_id=' . $app_id . '&redirect_uri=' . urlencode($my_url);

    echo("<script>top.location.href='" . $dialog_url . "'</script>");
  // get user access_token
  $token_url = '
     client_id=' . $app_id . '&redirect_uri=' . urlencode($my_url)
     . '&client_secret=' . $app_secret . '&code=' . $code;
  // response is of the format "access_token=AAAC..."
  $access_token = substr(file_get_contents($token_url), 13);
  // run fql query
  $fql_query_url = '' . 'fql?
     . '&access_token=' . $access_token;

  $fql_query_result = file_get_contents($fql_query_url);
  $fql_query_obj = json_decode($fql_query_result, true);
  // display results of fql query
  echo '<pre>';
  print_r("query results:");
  echo '</pre>';

Above is the same query to grab the logged in user’s name, profile picture, and email, but with the code to authenticate and run the query. Pretty simple right? Ok let’s amp things up.

Joining tables

Joining tables is something I find myself wanting to do quite often with API’s. I have one API endpoint and end up having to query another endpoint, often times in a loop, just to get the information I need. For example, with the Foursquare API if I am querying a users checkin history, via the checkin endpoint, and want to see the tips at the venue they checked in at, I have to query the venue endpoint with the venue id retrieved from the checkin endpoint. Obviously, looping through curls or file_get_contents is not ideal, and is usually very slow. With FQL, you can query multiple tables at once! Let’s write up a query to get the logged in user’s friends who like certain pages.

SELECT uid, page_id FROM page_fan WHERE uid IN (SELECT uid2 FROM
  friend WHERE uid1 = $user_id) AND page_id IN (104019549633137,
  84237528530, 51212153078, 57460905720, 54058402222, 106864538988,

As you can see we are querying both the friend table and the page_fan table. I know what you are thinking, the ability to join tables of an API just blew your mind and you can’t even begin to imagine what is next. You may want to sit down for this.


FQL allows multiple queries to be sent in one call. It’s basically like a batched request; it returns the data set for each query at one time. This saves so many server requests that would have been used to query the API multiple times. You can also reference previous queries in other queries. I know crazy right? Lets write up an example. This time I won’t tell you what it does until after.

// query 1
"all_friends":"SELECT uid FROM friend WHERE uid1 = me()"

// query 2
"online_friends":"SELECT uid2 FROM user WHERE online_presence IN
  ('active', 'idle') AND uid2 IN (SELECT uid FROM #all_friends)"

Yep, this gets the user’s current online friends. Now I know what you are thinking we could have joined tables instead and sent the request in one query. But, say you need the entire friends list AND the online friends list, then the query above would be perfect. As you can also see, to reference one query in another query you merely use a #. Let’s put this query into an example php call.

  // run fql multiquery
  $fql_multiquery_url = '' . 'fql?q=
     . '"online_friends":"SELECT+uid2+FROM+user+WHERE+online_presence
     +(SELECT+uid+FROM+#all_friends)"}' . '&access_token='
     . $access_token;

  $fql_multiquery_result = file_get_contents($fql_multiquery_url);
  $fql_multiquery_obj = json_decode($fql_multiquery_result, true);
  // display results of fql multiquery
  echo '<pre>';
  print_r("multi query results:");
  echo '</pre>';

The Facebook API may have a terrible reputation but there is something admirable about the familiarity of FQL. Granted it is not perfect, if you start querying the tables application, developer, or insights and find the columns in the documentation that should be there are not, don’t be surprised. But what do you expect from a company whose DNA is “Move fast, break things”? I do hope other API’s take after FQL and allow multiple queries to be sent at once. Big data is key in this day and age and the data available is constantly expanding. Best of luck on your future data mines, and try to keep in mind the positive side of FQL whenever the Graph API starts to drive you nuts.

Popular This Week
25 Must-Have Pages for Your E-commerce Website
January 30, 2015

25 Must-Have Pages for Your E-commerce Website

By Yvonne Weng
Building a Responsive jQuery Carousel Plugin from Scratch
November 26, 2014

Building a Responsive jQuery Carousel Plugin from Scratch

By Max Rolon
Taking Control of Image Loading
July 29, 2013

Taking Control of Image Loading

By Patrick Kunka
Text-align: Justify and RWD
March 12, 2013

Text-align: Justify and RWD

By Patrick Kunka

Like what you’re reading? Sign up for the Barrel newsletter and receive updates.