Last fall, I posted a post on Habré
Five ways to speed up Facebook API requests in practice , which turned out to be a good collection of recipes. During this time, the Facebook API has changed a lot, becoming even better. Now I rarely meet tasks with which I could not cope with a single HTTP request to the API. And all thanks to the new features, which I will talk about now.

Here are the ways that were last time:
- Requesting only required fields
me? fields = id, name, birthday - We request data of several objects in one request
? ids = 4,501012028 - We use filtering and pagination
me / friends? limit = 10 & offset = 10 - We use FQL queries
fql? q = SELECT uid, name, birthday_date FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1 = me ()) - We send Batch Request with several requests
batch = [{"method": "GET", "relative_url": "me"}, {"method": "GET", "relative_url": "me / friends? limit = 50"}]
All queries can be executed in the
Graph API Explorer , which now supports FQL queries.
')
1) Multi-query
Multi-query are several FQL queries that are sent in a single Graph API query. Multi-query are processed faster than the same FQL packet of requests sent via the Batch Request. At the same time, they not only can transmit the answer on several objects, but also solve one of the problems of simple FQL queries.
Suppose you want to get a list of users who are going to attend a certain event. You are writing a FQL query:
SELECT name, url, pic FROM profile WHERE id IN (SELECT uid FROM event_member WHERE eid = 12345678)But such a request gives you all users without giving status information (attending, unsure, declined, not_replied). All is well, if you need to display information only those who go to the event. Then you simply add
AND rsvp_status = 'attending' to the condition of the
subquery . But what do you do if on one page you need to display all the users, breaking them down by RSVP status. Make 4 FQL queries with different conditions and send them using batch?
Facebook invites you to make two requests and use the data of one in the second. For our example, the requests will be as follows:
"Query1": "SELECT uid, rsvp_status FROM event_member WHERE eid = 12345678""Query2": "SELECT name, url, pic FROM profile WHERE id IN (SELECT uid FROM # query1)"Now, in one request you will receive all the necessary data, and it will be faster than through batch.
Read more about Multi-query in the
documentation .
2) Batch Requests containing multiple methods and dependencies between operations
Now in one batch request you can pass different HTTP methods: GET, POST, DELETE. For example, publish a new status and return the user's news feed in one request. But the buns are not in this, but in “dependencies”.
Initially requests were independent. But now you can use the data of one request in another, while managing dependencies using
JSONPath expressions.
The simplest example: get the data of 5 friends. This can be done using this query:
batch = [{"method": "GET", "name": "get-friends", "relative_url": "me / friends? limit = 5",}, {"method": "GET", "relative_url" : "? ids = {result = get-friends: $. data. *. id}"}]Stop! So we can do the same with Multi-Query, you say. Yes, you need to pick another example to show all the power. And how about this one:
batch = [{"method": "GET", "name": "one-friend", "relative_url": "me / friends? limit = 1",}, {"method": "POST", "relative_url" : “Me / feed”, “body”: “message = {result = one-friend: $. Data.0.name} is my friend”}]We get one of the friends of the user and use his data in order to publish a new post. No need for two separate requests.
You can use up to 50 requests in batch, control the behavior of requests using the omit_response_on_success and depends_on parameters, and use different access_token (user, page, application) in different requests.
Batch Requests documentation.
3) ETags
At the beginning of the year, Facebook supported
HTTP ETags . The principle of their work is simple:
- When you execute a Graph API request, you will receive an ETag header with a value that is a hash of data returned via the API.
- The next time you call the same request, send an If-None-Match header with the data obtained from clause 1.
- If the data has not changed, you will receive in response 304 - Not Modified without data.
- If the data has changed - the data is returned as usual (point 1).
Use this preferably with data that does not change often. For example, you should not use ETags in news feed or post requests. But for friend list requests in mobile applications on slow connections, performance will certainly increase.
More about ETags as well as sample code you can see
in this post on the developer blog.
4) Field expansion
Above, I have already described two ways to get data from linked objects in a single request using Multi-query and Batch with JSONPath. But for the Graph API requests there is an easier option.
For example, we want to display the user name, his birthday and the last 10 photos on the page. We can do all this with this request:
me? fields = name, birthday, photos.limit (10) .fields (id, picture)Or we want to display comments on the photo, but standard fields are not enough for us, and we want to add another birthday of commentators. The request is as follows:
<photo_id> /comments?fields=from.fields (id, name, birthday)You can create such queries for all identifiers, fields and connections. Is not it much easier and more convenient?
Field expansion documentation.
5) Pagination
In the last article I already wrote about filtering and pagination using filter and offset. Although this method is very useful, but it still has one big drawback. In each query, you display the previous and next links regardless of whether there is data behind them or not.
Facebook offers a new solution: cursor-based offset paging. You will no longer show previous and next if there is no more data. If there is a previous / next page, the before / after links in the request will be displayed. You will save “one pass” by viewing each collection of objects.
Unfortunately, Cursor-based Pagination is not available for all objects yet. But it is a matter of time. Follow the
documentation and use more efficient solutions.
Well, if you have used all the features for optimization, do not forget to look at the article
Optimizing Facebook Graph API requests using Real-Time Updates .
In conclusion, I would like to remind you that Facebook Developer HACK 2012 will be in Moscow on October 1st. If you are unable to attend in person, leave your questions in the comments. Personally, I have accumulated enough questions for Facebook engineers.