DynamoDB is the obvious choice for AppSync as they together provide a truly serverless setup. DynamoDB tables can scale up and down easily and AWS also offers per-request pricing (called on-demand capacity). This makes it possible for the API to scale to any load and also to go back to zero.
Also, GraphQL's concept of many individual resolvers usually maps to DynamoDB tables easily. As it is a NoSQL database that does not support complex queries but has no problems handling tons of simple ones, it can work well with AppSync.
In this chapter we'll look into how to write resolvers that fetch and store data in DynamoDB and what are the best practices to adapt the data model for efficient GraphQL queries.
When you create a DynamoDB data source, you need to define a table and a role. The form defines what table to send the requests (except when it needs to be defined by the resolver, such as for transactions as we'll see later), and the latter gives AppSync permissions to do the operations.
With the IAM role setting, you can give fine-grained permissions for each data source. For example, if you don't add write permissions then AppSync won't be able to change data in the table.
With a data source per table, you have the choice to use a separate role for each of them, in contrast to using a single role with all permissions AppSync needs.
So, which approach is better?
I found that using separate roles adds too much verbosity and brings very little benefits. Since it brings no security benefits, I usually go with a single role per AppSync API.