Objectify return List & Cursor
Asked Answered
H

2

5

I am trying to use a cursor with Objectify and Google App Engine to return a subset of data and a cursor so that I can retrieve more data when the user is ready. I found an example here that looks exactly like what I need but I don't know how to return the final list plus the cursor. Here is the code I have:

@ApiMethod(name = "listIconThemeCursor") //https://code.google.com/p/objectify-appengine/wiki/Queries#Cursors
public CollectionResponse<IconTheme> listIconThemeCursor(@Named("cursor") String cursorStr) {
    Query<IconTheme> query = ofy().load().type(IconTheme.class).limit(10);
    if (cursorStr != null ) {
        query.startAt(Cursor.fromWebSafeString(cursorStr));
    }
    List<IconTheme> result = new ArrayList<IconTheme>();
    int count = 0;
    QueryResultIterator<IconTheme> iterator = query.iterator();
    while (iterator.hasNext()) {
        IconTheme theme = iterator.next();
        result.add(theme);
        count++;
    }
    Cursor cursor = iterator.getCursor();
    String encodeCursor = cursor.toWebSafeString();
    return serial(tClass, result, encodeCursor);
}

Note that this was modified from a previous endpoint in which I returned the CollectionResponse of ALL the data. My dataset is large enough that this is no longer practical. Basically, I don't know what was in the user's function of 'serial(tClass, result, encodeCursor) that let it get returned to the user.

There is another example here but it doesn't appear to answer my question either.

Heliotrope answered 15/8, 2014 at 2:3 Comment(0)
A
5

I don't quite understand what you are asking, but I see one immediate bug in your code:

query.startAt(Cursor.fromWebSafeString(cursorStr));

...should be:

query = query.startAt(Cursor.fromWebSafeString(cursorStr));

Objectify command objects are immutable, functional objects.

Alluvial answered 15/8, 2014 at 7:46 Comment(2)
Nice catch on that (I'm sure it would have killed me later). Basically though, I don't know what 'return serial(tClass, result, encodeCursor) is. I only know how to return a CollectionResponse, not how to return the ArrayList + Cursor.Heliotrope
This is a question for someone familiar with Google Endpoints. I suggest you tag the question with the google endpoints tag to get the right eyes on it.Alluvial
H
5

After a long slog, I figured out that CollectionResponse has the cursor in it :(

Here is the complete code I used incorporating the comment from stickfigure above:

   @ApiMethod(name = "listIconThemeCursor", path="get_cursor") 
    public CollectionResponse<IconTheme> listIconThemeCursor(@Named("cursor") String cursorStr) {
        Query<IconTheme> query = ofy().load().type(IconTheme.class)
                .filter("errors <", 10)
                .limit(10);
        if (cursorStr != null ) {
            query = query.startAt(Cursor.fromWebSafeString(cursorStr));
        }
        List<IconTheme> result = new ArrayList<IconTheme>();
        QueryResultIterator<IconTheme> iterator = query.iterator();
        while (iterator.hasNext()) {
            IconTheme theme = iterator.next();
            result.add(theme);
        }
        Cursor cursor = iterator.getCursor();
        CollectionResponse<IconTheme> response = CollectionResponse.<IconTheme> builder()
                .setItems(result)
                .setNextPageToken(cursor.toWebSafeString())
                .build();

        return response;
    }
Heliotrope answered 16/8, 2014 at 2:21 Comment(3)
Really appreciate this. Can't find CollectionResponse Javadocs, so this was hugely helpful.Celerity
Should cursorStr also be @Nullable?Celerity
I guess it could @Celerity but it will run just fine without it.Heliotrope

© 2022 - 2024 — McMap. All rights reserved.