batch request with dependancies

53 views
Skip to first unread message

Andy Waddell

unread,
Feb 6, 2012, 7:31:05 PM2/6/12
to BatchFB
I've been trying to create a batch to get all the photo albums and
then all the photos in each album. I can make it work with curl by
following the example here: http://developers.facebook.com/docs/reference/api/batch/

but with I tried it with batchfb I get "ERROR: Request 1 cannot depend
on an unresolved request with name get-albums. Requests can only
depend on preceding requests"

any clues welcome.

curl \
-F 'access_token=... your token here ' \
-F 'batch=[{ "method": "GET", "name" : "get-albums",
"relative_url": "me/albums?limit=5", }, { "method": "GET",
"relative_url": "?ids={result=get-albums:$.data.*.id}" }]'
https://graph.facebook.com/


FacebookBatcher batcher = new FacebookBatcher(access_token);
batcher.setTimeout(5000);
Later<JsonNode> albumsNode = batcher.graph("me/albums",
JsonNode.class, new Param("name", "get-albums"));
Later<JsonNode> albumPhotos = batcher.graph("?ids={result=get-albums:
$.data.*.id}", JsonNode.class);

try {
JsonNode albums = albumsNode.get();

System.out.println(albums);
System.out.println(albumPhotos);
} catch (FacebookException fbex) {
System.out.println("ERROR: " + fbex.getMessage());
}

Andy Waddell

unread,
Feb 6, 2012, 7:48:21 PM2/6/12
to BatchFB
After some further debugging I see that the request is going out as:
[ { "method" : "GET",
"relative_url" : "me/albums?name=get-albums"
},
{ "method" : "GET",
"relative_url" : "?ids={result=get-albums:$.data.*.id}"
}
]

Is there a way to set the name field correctly?

Jeff Schnitzer

unread,
Feb 9, 2012, 3:27:50 PM2/9/12
to bat...@googlegroups.com
Notice that the object that comes back from graph() is a GraphRequest<T> (which implements Later<T>):

public GraphRequest<JsonNode> graph(String object, Param... params);

The GraphRequest<T> has a method setName().  So you can do this:

GraphRequest<JsonNode> request = batcher.graph("me/albums");
request.setName("get-albums");
JsonNode node = request.get();

This would actually be a lot more convenient if setName() was chainable so you could do this:

GraphRequest<JsonNode> request = batcher.graph("me/albums").setName("get-albums");

I will modify trunk right now.

Jeff

Andy Waddell

unread,
Feb 9, 2012, 3:30:49 PM2/9/12
to BatchFB
Awesome.. thanks.

On Feb 9, 12:27 pm, Jeff Schnitzer <j...@infohazard.org> wrote:
> Notice that the object that comes back from graph() is a GraphRequest<T>
> (which implements Later<T>):
>
> public GraphRequest<JsonNode> graph(String object, Param... params);
>
> The GraphRequest<T> has a method setName().  So you can do this:
>
> GraphRequest<JsonNode> request = batcher.graph("me/albums");
> request.setName("get-albums");
> JsonNode node = request.get();
>
> This would actually be a lot more convenient if setName() was chainable so
> you could do this:
>
> GraphRequest<JsonNode> request = batcher.graph("me/albums"
> ).setName("get-albums");
>
> I will modify trunk right now.
>
> Jeff
>

Jeff Schnitzer

unread,
Feb 9, 2012, 3:33:53 PM2/9/12
to bat...@googlegroups.com
Ok the setName() method is now chainable, although it returns a Request<T> not the specific GraphRequest<T> or QueryRequest<T> (both share the common base class).  This shouldn't matter much in practice.  If it does, I can play some more tricks with generics to make it return the right type.

Jeff

roee88

unread,
Feb 13, 2012, 8:36:43 AM2/13/12
to BatchFB
Is it possible to do the same using the query method and not graph
(i.e. using FQL multiquery)?
Like the example here: http://developers.facebook.com/docs/reference/rest/fql.multiquery/
where query2 uses the result of query1.

On Feb 9, 10:33 pm, Jeff Schnitzer <j...@infohazard.org> wrote:
> Ok the setName() method is now chainable, although it returns a Request<T>
> not the specific GraphRequest<T> or QueryRequest<T> (both share the common
> base class).  This shouldn't matter much in practice.  If it does, I can
> play some more tricks with generics to make it return the right type.
>
> Jeff
>
>
>
>
>
>
>
> On Thu, Feb 9, 2012 at 3:27 PM, Jeff Schnitzer <j...@infohazard.org> wrote:
> > Notice that the object that comes back from graph() is a GraphRequest<T>
> > (which implements Later<T>):
>
> > public GraphRequest<JsonNode> graph(String object, Param... params);
>
> > The GraphRequest<T> has a method setName().  So you can do this:
>
> > GraphRequest<JsonNode> request = batcher.graph("me/albums");
> > request.setName("get-albums");
> > JsonNode node = request.get();
>
> > This would actually be a lot more convenient if setName() was chainable so
> > you could do this:
>
> > GraphRequest<JsonNode> request = batcher.graph("me/albums"
> > ).setName("get-albums");
>
> > I will modify trunk right now.
>
> > Jeff
>

Jeff Schnitzer

unread,
Feb 13, 2012, 4:24:49 PM2/13/12
to bat...@googlegroups.com
Yes, the QueryRequest has the same setName() method:

QueryRequest<Foo> req = batcher.query("select blah...");
req.setName("whatever");

or if you're using trunk, you can chain it:  batcher.query("...").setName("...")

Jeff

uri

unread,
Feb 28, 2012, 9:34:40 AM2/28/12
to bat...@googlegroups.com
Hi, 

How can I use the chaining option with 'post'? 
The batcher.post(...) method returns a Later<...> and this interface doesnt declare setName(). 
Currently I've to do the following, which works, yet its not a good nor recommended practice:

Later<T> later = batcher.post(...);
((Request<T>) later).setName(...);

Thanks,
Uri

Jeff Schnitzer

unread,
Feb 28, 2012, 9:46:16 AM2/28/12
to bat...@googlegroups.com
Interesting, that never occurred to me.

I just checked in a change; the <T> generic post() method now returns a GraphRequest.

The post() that returns String is still Later because it does additional manipulation of the return data; what you get back isn't actually a String but a json structure containing a String.  It would be confusing to try to use this via JSONP.

Jeff

uri

unread,
Feb 28, 2012, 9:57:29 AM2/28/12
to bat...@googlegroups.com
you're fast!
thanks,
uri
Reply all
Reply to author
Forward
0 new messages