Skip to content
Alex Koppel edited this page Feb 28, 2017 · 11 revisions

Facebook makes it easy to send multiple requests at once, which is way faster than sending them all individually.

Here are some Batch Request examples taken directly from the test cases. It's nicely self-explanatory.

Make sure to read Facebook's documentation, it's very useful. Note that you can currently only make up to 50 requests at once, so if you have more to make you'll need to split them up (see example at the bottom of the page).

before :each do
  @api = Koala::Facebook::API.new(my_access_token)
end

it "can get two results at once" do
  me, facebook = @api.batch do |batch_api|
    batch_api.get_object('me')
    batch_api.get_object('facebook')
  end
  me['id'].should_not be_nil
  facebook['id'].should_not be_nil
end

it 'should be able to make mixed calls inside of a batch' do
  me, friends = @api.batch do |batch_api|
    batch_api.get_object('me')
    batch_api.get_connections('me', 'friends')
  end
  me['id'].should_not be_nil
  friends.should be_an(Array)
end

it 'should be able to make a get_picture call inside of a batch' do
  pictures = @api.batch do |batch_api|
    batch_api.get_picture('me')
  end
  pictures.first.should_not be_empty
end

it "should handle requests for two different tokens" do
  me, insights = @api.batch do |batch_api|
    batch_api.get_object('me')
    batch_api.get_connections(@app_id, 'insights', {}, {"access_token" => @app_api.access_token})
  end
  me['id'].should_not be_nil
  insights.should be_an(Array)
end

it "inserts errors in the appropriate place, without breaking other results" do
  failed_insights, koppel = @api.batch do |batch_api|
    batch_api.get_connections(@app_id, 'insights')
    batch_api.get_object("koppel", {}, {"access_token" => @app_api.access_token})
  end
  failed_insights.should be_a(Koala::Facebook::APIError)
  koppel["id"].should_not be_nil
end

it "handles different request methods" do
  result = @api.put_wall_post("Hello, world, from the test suite batch API!")
  wall_post = result["id"]

  wall_post, koppel = @api.batch do |batch_api|
    batch_api.put_like(wall_post)
    batch_api.delete_object(wall_post)
  end
end

it "posts binary files" do
  file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))

  Koala::Facebook::BatchOperation.instance_variable_set(:@identifier, 0)
  result = @api.batch do |batch_api|
    batch_api.put_picture(file)
  end

  @temporary_object_id = result[0]["id"]
  @temporary_object_id.should_not be_nil
end

it "posts binary files with multiple requests" do
  file = File.open(File.join(File.dirname(__FILE__), "..", "fixtures", "beach.jpg"))

  Koala::Facebook::BatchOperation.instance_variable_set(:@identifier, 0)
  results = @api.batch do |batch_api|
    batch_api.put_picture(file)
    batch_api.put_picture(file, {}, "koppel")
  end
  results[0]["id"].should_not be_nil
  results[1]["id"].should_not be_nil
end
it "allows you create relationships between requests without omit_response_on_success" do
  results = @api.batch do |batch_api|
    batch_api.get_connections("me", "friends", {:limit => 5}, :batch_args => {:name => "get-friends"})
    batch_api.get_objects("{result=get-friends:$.data.*.id}")
  end

  results[0].should be_nil
  results[1].should be_an(Hash)
end

it "allows you create relationships between requests with omit_response_on_success" do
  results = @api.batch do |batch_api|
    batch_api.get_connections("me", "friends", {:limit => 5}, :batch_args => {:name => "get-friends", :omit_response_on_success => false})
    batch_api.get_objects("{result=get-friends:$.data.*.id}")
  end

  results[0].should be_an(Array)
  results[1].should be_an(Hash)
end

it "allows you to create dependencies" do
  me, koppel = @api.batch do |batch_api|
    batch_api.get_object("me", {}, :batch_args => {:name => "getme"})
    batch_api.get_object("koppel", {}, :batch_args => {:depends_on => "getme"})
  end

  me.should be_nil # gotcha!  it's omitted because it's a successfully-executed dependency
  koppel["id"].should_not be_nil
end

it "properly handles dependencies that fail" do
  data, koppel = @api.batch do |batch_api|
    batch_api.get_connections(@app_id, 'insights', {}, :batch_args => {:name => "getdata"})
    batch_api.get_object("koppel", {}, :batch_args => {:depends_on => "getdata"})
  end

  data.should be_a(Koala::Facebook::APIError)
  koppel.should be_nil
end

it "throws an error for badly-constructed request relationships" do
  expect {
    @api.batch do |batch_api|
      batch_api.get_connections("me", "friends", {:limit => 5})
      batch_api.get_objects("{result=i-dont-exist:$.data.*.id}")
    end
  }.to raise_exception(Koala::Facebook::APIError)
end

Example of slicing requests into groups of 50 to comply with Facebook limits:

# example from test_users.rb
test_user_list.each_slice(50) do |users|
  self.api.batch(options) {|batch_api| users.each {|u| batch_api.delete_object(u["id"]) }}
end
Clone this wiki locally