Skip to content

Graph API

Skip Gibson edited this page Apr 13, 2016 · 49 revisions

The Graph API is the core of Facebook’s new interface. Let’s play with it.

Graph API in your browser!

Important side note: did you know you can play with the Graph API in your browser? It’s one of my favorite aspects of the API. Facebook has released a Graph API Explorer, which lets you get an access token and explore the Graph easily. You can also make requests directly in your browser; for each example coming up, I include a link to the equivalent query. (If you haven’t been to http://graph.facebook.com, you should definitely click through and play with the results. Try your own nickname!)

Since I’m abbreviating the API results for space, I strongly encourage you to check it out.

Initializing

First, you need to create your API object that you will use to make your calls. If you want, you can also pass an access token to access private or restricted data, as explained in the “Getting Private Data” section of this page.

@graph = Koala::Facebook::GraphAPI.new # pre 1.2beta
@graph = Koala::Facebook::API.new # 1.2beta and beyond

Note that you can also use the GraphAndRestAPI class, which allows all-in-one access to both the Graph and Rest API.

Getting public data

Let’s get some data from Facebook.  To learn about an object, just use the get_object method.  For instance, you can learn about people:

# http://graph.facebook.com/koppel
@graph.get_object("koppel")
# => {"name"=>"Alex Koppel", "id"=>"2905623", "last_name"=>"Koppel", "link"=>"http://www.facebook.com/koppel", "first_name"=>"Alex"}

And Pages:

# http://graph.facebook.com/contextoptional
@graph.get_object("contextoptional")
# => {"name"=>"Context Optional, Inc.", "id"=>"7204941866", ....}

You can get certain also Page’s feed:

# http://graph.facebook.com/contextoptional/feed
client = Koala::Facebook::API.new(oauth_token)
client.get_connection('someuser', 'posts',
                    {limit: @options[:max_items],
                      fields: ['message', 'id', 'from', 'type',
                                'picture', 'link', 'created_time', 'updated_time'
                        ]})

Note: You can pass a ‘type’ hash key with a value of ‘small’, ‘normal’, ‘large’, or ‘square’ to obtain different picture sizes, with the default being ‘square’. Also, you may need the user_photos permission.

As well as details about individual public stories:

# http://graph.facebook.com/7204941866_117111188317384
@graph.get_object("7204941866_117111188317384")  # remember this ID
# => {"name"=>"Bare Escentuals Cosmetics",
#     "message"=>"We've just launched the Bare Escentuals "Mom & Me" application!",
#     "likes"=>3,
#     ....
#    }

If you want to retrieve several objects without having to make a bunch of facebook calls, just call the get_objects method.

# https://graph.facebook.com/?ids=109856845694262,103914006312563
@graph.get_objects([109856845694262,103914006312563])
# => {"109856845694262" => {"id"=>"109856845694262", "name"=>"Cupe Coy, Netherlands Antilles", . . .       },
#     "103914006312563" => {"id"=>"103914006312563", "name"=>"Perrine, Florida", . . . }}

Getting Private Data

Public data’s cool, but it’s often not enough. You want to know who your users are — their full details, their likes, their feed, their friends. Without an access token, you can’t get that:

@graph.get_connections("koppel", "likes")
# => Koala::Facebook::APIError: An access token is required to request this resource.

We’ll go over getting an access token in a moment. For now, head over to https://developers.facebook.com/docs/graph-api — Facebook’s Graph API developer site has a bunch of links, any of which will provide you with an access token. Copy that from the URL, and check out what you can do now:

# first, initialize a Graph API with your token
@graph = Koala::Facebook::GraphAPI.new(your_oauth_token) # pre 1.2beta
@graph = Koala::Facebook::API.new(your_oauth_token) # 1.2beta and beyond
 
# now, try that query again
# http://graph.facebook.com/koppel/likes?access_token=#{your_oauth_token}
@graph.get_connections("koppel", "likes")
# => [{"name"=>"Mechanics' Institute Library", ....}]

“me” is a very useful shortcut Facebook provides to getting the current user:

# http://graph.facebook.com/me?access_token=#{your_oauth_token}
@graph.get_object("me")
# => {"name"=>"Alex Koppel", ....}

Some newer Facebook calls take three parts — for instance, let’s say you want to get a user’s mutual friends. Easy:

# https://graph.facebook.com/me/mutualfriends/FRIEND_ID
@graph.get_connections("me", "mutualfriends/#{friend_id}")
# => [{"name"=>"Alex Koppel", ....}, ....]

With a user’s access token, you get any public information, plus additional information through extended permissions (see the OAuth section).

You can also search for users/pages/events/groups for the keyword of your choice:

# http://graph.facebook.com/search?q=koala&type=place
@graph.get_connection('search', type: :place)
# => [{"category"=>"Attractions/things to do", ...
#     "name"=>"Maru Koala & Animal Park"}]}

Writing to the Graph

Reading’s all well and good, but no discussion of the graph would be complete without some writing. In order to write to the social graph, you’ll need to prompt your user for the publish_stream extended permission (see the OAuth section).

For the sake of simplicity, let’s assume the token we got above has the right permissions; otherwise, you’ll get an error. (Since writing to the graph involves sending POST requests, the browser follow-along unfortunately has to end.)

Let’s start by posting to our own walls using the put_wall_post method.

@graph.put_wall_post("hey, i'm learning koala")
# => {"id"=>"2905623_123183957698327"}

Oops — we misspelled Koala! How embarrassing.

@graph.delete_object("2905623_123183957698327")
# => true

Let’s never speak of that again, okay?

You can also write to other people’s walls. For instance, I’ll send a link to a cool (if sappy) comic to my husband.

@graph.put_wall_post("explodingdog!", {:name => "i love loving you", :link => "http://www.explodingdog.com/title/ilovelovingyou.html"}, "tmiley")
#=> {"id"=>"83901496_520908898070"}

Side note: put_wall_post posts to user/feeds, which doesn’t include a Share button. To get one when posting a link, you can use put_connections(user, “links”, hash_of_details).

Speaking of family, Mother’s Day was coming up when I wrote this. Let’s go back to that earlier post about the Mother’s Day app my company just released, and like it.

@graph.put_like("7204941866_117111188317384")
# => true

Now it has 4 likes:

@graph.get_object("7204941866_117111188317384")
# => {"message"=>"We've just launched the Bare Escentuals "Mom & Me" application", "likes"=>4...}

Actually, changed my mind. I’m not a huge cosmetics fan.

@graph.delete_like("7204941866_117111188317384")
# => true

Personal confession: I still haven’t picked out a gift for my mom. What’s Facebook for, if not to talk about things like that?

@graph.put_comment("7204941866_117111188317384", "Can't believe Mother's Day's just a week away!  I'd better get on that gift.")
# => {"id"=>"7204941866_117111188317384_448625"} # ID of the comment

Turned out to be quite the adventure, so I’ll post a note about it:

@graph.put_connections("me", "notes", :subject => "Finding my mom a gift: An Epic Odyssey", :message=> all_the_details)
# this works for other connections too -- links, events, etc.
# def put_connections(id, connection_name, args = {}, options = {})

That’s more or less it for the Graph API. All the calls you just saw wrap a few generic methods (get_object, get_connections, put_connections, delete_object, etc.), which allow you access to the entire Graph API. Facebook has done a great job of designing the API and keeping interface stable and consistent; these basic accessors should function for all the methods out there and (so far so good) anything new they release in the future.

Retrieving Pages of Results

Thanks to jagthedrummer for this contribution!

When fetching data from Facebook that returns a list of results (i.e. using API#get_connections or API#search) Facebook returns a limited number of results per request. To help make paging through these results easier, Koala returns a GraphCollection object, a subclass of Array, that includes a few methods to ease getting the next and previous pages of results.

@result = @graph.get_connections('me', 'feed')
@result.class
# => Koala::Facebook::GraphCollection

# You can use a GraphCollection just like a normal Array or results
@result.first
# => {"actions" => [], "message" => "This my feed message.", ...}

To get the next (or previous) page of results, use the next_page (or previous_page) method on a GraphCollection.

@next_page = @result.next_page
# => [{"actions" => [], "message" => "This my feed message.", ...}, ...] 

@next_page.class
# => Koala::Facebook::GraphCollection

Paging Across Multiple (User) Requests

While paging through results is fun, most of the time you’ll want to fetch the next page of results only when requested by the user. The next_page_params and previous_page_params methods in conjunction with API#get_page method makes this a snap.

API#next_page_params returns an array with two entries describing the API URL to fetch the next page of results: the path and a hash of parameters.

@results.next_page_params
# => ['"me/feed", {"limit => "25", "access_token" => "...", ...}]

Using the result of next_page_params as the single argument to API#get_page you can retrieve the next page of your results.

Here’s an example using Rails (see below for other frameworks):

# /app/controllers/foo_controller.rb
def index
  # get the first page, or a next/previous page if appropriate params are sent
  @results = params[:page] ? @graph.get_page(params[:page]) : @graph.get_connections("me", "feed")
end
# /app/views/foo/index.html.erb
<% @results.each do |result| %>
  <!-- Display each result -->
<% end %>

<%= link_to 'Previous', url_for(:page => @results.previous_page_params) %>
<%= link_to 'Next', url_for(:page => @results.next_page_params) %>

Notice that API#get_connections only needs to be called once, when you fetch the first page of results. By using next_page_params to populate the “page” URL parameter, you can use params[:page] as a single parameter to API#get_page to get the next set of results (as above).

This example takes advantage of how Rails serializes an array as URL parameters (and how Rails interprets URL parameters when handling requests.) Even without this functionality, however, creating appropriate parameters to use from next_page_params should be fairly straight forward — if you’re using Sinatra or another framework, check out this comment for an example of how to traverse pages without using the Rails helpers.

Special Topics

A few Graph API odds and ends that have come up over the years.

Adding the Share action to your links

Koala’s put_wall_post posts to user/feeds (reflecting the design of Facebook libraries), which doesn’t include a Share button. To get one when posting a link, you can use put_connections(user, “links”, hash_of_details). Be aware, though, that as of this writing, not every argument is recognized when posting to links (in particular, name, description, and picture aren’t always respected — this may be fixed by the time use it).

Posting unencoded text

In rare cases it can be useful to post unencoded parameters directly to Facebook — for instance, at one point posting certain strings (like <center></center> or %0D%0A) would add a line break to a wall post. All Koala form parameters are URL encoded, but it’s easy to post unencoded strings by constructing parameters yourself:

# this is posted without encoding and (at one time) would show up on two lines
@graph.put_connections("me", "feed?message=foo%0D%0Abar")

If the Graph API returns false

In some cases — for instance, if the user has opted out of the Facebook Platform entirely — your Graph API calls may return false instead of the expected object. It’s rare, but it does happen — something to keep in mind as you develop. See http://forum.developers.facebook.net/viewtopic.php?id=61050.

API Changes in 1.2

With Koala 1.2, we consolidated all the API classes into Koala::Facebook::API. If you’re still using an earlier version, use the GraphAPI, RestAPI, or (best) GraphAndRestAPI as appropriate. The older classes will continue to work as expected with 1.2 and beyond, though with a deprecation warning.

Something went wrong with that request. Please try again.