Implementing pagination with DynamoDB
See original GitHub issueI’ve decided to make a pagination in my app. But I’ve troubles with the backward paginating.
My resolvers are connected to the DynamoDB. When you want to get the previous “page” of your data you will need specify "scanIndexForward": false
in your query to switch scan direction throw the data table. This attribute works only with "Query"
operation not with "Scan"
. And the troubles become here because in "expression"
attribute you’ll need set expression with the following condition:
The partition key equality test is required, and must be specified in the following format:
partitionKeyName = :partitionkeyval
If you also want to provide a condition for the sort key, it must be combined using AND with the condition for the sort key. Following is an example, using the = comparison operator for the sort key:
partitionKeyName = :partitionkeyval AND sortKeyName = :sortkeyval
as says DynamoDB reference. So when I’m specifying partitionKeyName = :partitionkeyval
I’ll getting only one item and I can’t get multiple items because of “=” operator in "expression"
. Operation "Scan"
returns multiple items but it doesn’t support "scanIndexForward"
option.
Am I doing all right? Or is there another way to implement prev pagination?
And is it possible to implement pagination with the numbered pages not only previous/next ones?
Issue Analytics
- State:
- Created 6 years ago
- Comments:5 (1 by maintainers)
Top GitHub Comments
I’m no DynamoDB expert, but doesn’t
scanIndexForward
simply reverse the list of results? So if your data comes back A-Z,scanIndexForward: false
will make it come back Z-A. It doesn’t paginate backwards.I’m using pagination in my Vue app with AppSync, so maybe I can help with a couple things.
First off, you hardly ever want to use the scan operation on DynamoDB. It reads every single item in your table, which will wind up consuming your read capacity. In 95% of the cases, you want to use query to list a bunch of things.
This leads to the next question: how do you query a bunch of items instead of just a single item (partition key)? Your data may not be structured correctly. As a rudimentary example, let’s say you have a database of gadgets, and each gadget is owned by a single user. Thinking in terms of traditional databases, you might have the primary key be
gadgetId
, but in DynamoDB this is not correct. This is how you might structure it:So the user with ID
0515dc74
logs in, and you want to show them all the gadgets they own. You would do a query operation on just the partition key,userId = 0515dc74
. This will return the four items above. If you want to grab just one specific one, you’d do aGetItem
request on both the partition key and sort key.Now onto pagination.
You’re correct that you cannot jump to a specific page number. With DynamoDB pagination, you can only move forwards or backwards. So what you’ll have to do as a user pages through their items is keep a history of all
nextToken
s given to you. Maybe store them in an array (tokens.push()
) as they page through, and usetokens.pop()
to pop off a token when they page backwards.The other thing to be wary of with AppSync is that (currently, anyway), it’s not always correct when it thinks there are more pages. A scenario where it will falsely give you a
nextToken
is when (for example) you have 40 items total, and you’re showing 10 per page. On the 4th page, AppSync has no idea if there are more items or not, so you’ll get anextToken
which will yield an empty result set if you query using it. The workaround is to always do a “lookahead” query usingnextToken
and manually check if that result set is empty. If it is, then don’t allow the user to page forward. It’s a bit hacky, but the team is looking into this.Hope some of that is helpful!
It’s hard to find some detailed responses like @ffxsam one. So I really appreciate it.