Batch requests

arsduo edited this page Jul 21, 2012 · 10 revisions

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, koppel = @api.batch do |batch_api|
    batch_api.get_object('me')
    batch_api.get_object('koppel')
  end
  me['id'].should_not be_nil
  koppel['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 "allows FQL" do
  result = @api.batch do |batch_api|
    batch_api.fql_query("select name from user where uid=4")
  end

  fql_result = result[0]
  fql_result[0].should be_a(Hash)
  fql_result[0]["name"].should == "Mark Zuckerberg"
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