AWS Amplify is something roughly analogous to Firebase -- it attempts to provide all of the tools that you need to write a basic app. AWS delivers this as a framework that uses (and provides an overlay on) other AWS services such as Cognito, AppSync, and DynamoDB. However, the abstraction can be quite leaky at times and lead to a lot of counter-intuitive situations (especially for people coming from a more traditional RDBMS) that can only really be explained by examining the underlying technology.
What happens when you run the below query on the below table?
Name | Enabled |
---|---|
Alice | True |
Bob | False |
Carol | True |
query {
listPeople(
limit: 2,
filter: {
enabled: { eq: true }
}
) {
items {
name
enabled
}
nextToken
}
}
Turns out you get one record for Alice.
Name | Enabled |
---|---|
Alice | True |
This happens because AppSync implements the list operation as a scan and will scan a maximum of two records (because of limit: 2
) and filter those two records on the enabled property. You will also be billed for scanning two records, even though only one was returned.
Your app might not use the filter feature. Of course, DynamoDB and AppSync both only support message sizes up to 1 MiB, so you can still run into this issue if your result set exceeds 1 MiB.
Maybe your users won't care if they request a page of 100 records and only get 89 back -- they'll just click over to the next page. They probably will care if they get 0 records back on a page though. Amplify implements filtering by owner
as a DynamoDB filter in the generated VTL for AppSync, so if you have over 100 users you better be prepared to get a few pages of 0 results before your customer sees any of their data (if they haven't dismissed your app as not working and closed it). I guess you'll need to add custom listByOwner
GSIs to all of your types.
The Amplify documentation suggests using the usePagination
hook with the GraphQL limit parameter and saving a nextToken
for each page...