When initializing a new GraphQL backend via the Amplify CLI, the sample schema defines multiple types with the @model annotation. For example...
type Blog @model { id: ID! name: String! posts: [Post] @connection(name: "BlogPosts") } type Post @model { id: ID! title: String! blog: Blog @connection(name: "BlogPosts") comments: [Comment] @connection(name: "PostComments") } type Comment @model { id: ID! content: String post: Post @connection(name: "PostComments") }
When pushed, this results in the creation of multiple DynamoDB tables (one per model). So in this example, three separate DynamoDB tables are created (Blogs, Posts, and Comments)
In our case we have a Users
model and we're going to have twenty or so small collections associated to the user. I feel uneasy about having to manage twenty different DynamoDB tables when it feels like these small collections all belong with the User object in a single table.
From everything I'm reading it seems like AppSync is encouraging the use of multiple tables. For example, the Note in the screenshot below from the AWS AppSync documentation specifically calls out that the blog comments should go into a separate table in a production environment.
This contradicts the best practice laid out in the DynamoDB documentation:
You should maintain as few tables as possible in a DynamoDB application. Most well designed applications require only one table.
Is it truly the case that when using AppSync each type belongs in a separate DynamoDB table?
The Amplify CLI provides support for AppSync that make this process easy. Using the CLI, you can configure an AWS AppSync API, download required client side configuration files, and generate client side code within minutes by running a few simple commands on the command line.
AWS Amplify CLI is a unified toolchain to create, integrate, and manage the AWS cloud services for your app. Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure REST APIs at any scale.
AWS Amplify can integrate with any GraphQL provider to perform queries and real-time data subscriptions via it's easy to use GraphQL client. AWS AppSync extends GraphQL's capabilities even more by offering enterprise-level security, real-time data synchronization, and orchestration of backend data resources.
AppSync is a powerful service by AWS that allows you to deploy GraphQL APIs with ease, as well as connect those APIs with data sources like AWS DynamoDB, lambda, and more. It can work without Amplify, but when you pair Amplify with it, you get some extra benefits. Deployment, for example, is way easier.
As you mentioned, the DynamoDB documentation suggests that “most well designed applications only require a single table”. This is valid for many applications when developers have learned, over the course of time, their data access patterns, settled on a data model, and have certain scale requirements that need to be optimized. Many developers do not have this level of understanding of their application from day 1 or necessarily the same requirements. Additionally some of the points mentioned in the presentations on single table design (e.g. tradeoffs between storage costs vs compute) can be subjective based on your application.
When you are building a new app or do not know your data access pattern, the benefits of using the single table design pattern has diminishing results and the multiple tables strategy is much more flexible.
AWS amplify is an opinionated client framework providing sensible defaults for developers who have different levels of scale and complexity, as such it has adopted a multiple table strategy when leveraging the @model transformer in its most basic form. As your requirements evolve, you can augment this design by using additional features of the Transformer such as @key (for creating single table indexes and composite keys) or even full text search & streaming from DynamoDB with @searchable.
We do recognize that large scale or mature apps might benefit of a single table approach. Going from multiple tables to single table is probably a one time “merge” operation, after the prototyping phase, and when data access patterns have been understood by the developer. In reality there is not a “one size fits all approach” which is why Amplify’s GraphQL Transformer gives you different levels of flexibility depending on where your app is at in its evolution.
As Luis mentioned in another answer: AWS AppSync does support any type of table structure independent of the GraphQL Transformer generation pattern. Even if you do have more than one table, you can easily implement GraphQL relational patterns in a single client request either with schema design, nested resolvers, or even implementing Pipeline resolvers.
(this response was redacted with the help of Richard)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With