Making DynamoDB Pleasant With Amplify DataStore
Possibly one of the most under-appreciated features of Amplify
I am a big fan of Amplify. I have used it extensively and for years. Among other things, we use Amplify in production at Trilo to interface with our unified GraphQL API (powered by AppSync).
One feature that I've been wanting to test out for a while is Amplify DataStore. As previously mentioned, I have been building a new project recently; so after mapping out all the pros and cons, I decided to use DataStore for this project.
Amplify DataStore is a library of AWS Amplify. It allows developers to build offline-enabled applications with the ease of an old-fashioned ORM.
In this post, I'm going to share a few thoughts about my experience working with Amplify DataStore.
ORM + DynamoDB = 🚀
Some of us who have worked with Ruby on Rails, Django, Symfony, or other monolithic frameworks that used to be all the rage years ago, may be familiar with how easy and quick it is to get something up and running when using an ORM.
With its ORM-like experience, Amplify DataStore makes it easier to start out a new project as a Serverless Monolith (i.e. without a lot of the bells and whistles you'd expect from a high-scale, enterprise-ready serverless application).
The syntax for querying an item from the database, for example, looks something like this:
const post = await DataStore.query(Post, "1234567");
That's a far cry from the many lines of code required to run a simple query with standard Dynamo DB.
Offline Capabilities
In contrast with standard DynamoDB or even AppSync, Amplify DataStore comes with offline support.
This is quite cool and makes it easier to identify obvious use cases for it. If you're building an application that needs to continue working offline (for example, a real-time collaboration app) then DataStore is for you.
You could, of course, handle the local/offline side of things yourself while continuing to use DynamoDB in the backend, but Amplify DataStore makes it harder to justify building all of that on your own.
Visual Data Modelling
Within Amplify Studio (which is one of my favourite things about Amplify) you get to design your data models, establish relationships, validation rules, and authorisation.
I cannot overstate how efficient this is! It takes away so many steps usually required when building a data model in DynamoDB.
Within minutes, I can add a new type to my data model, set up its rules and relationships, and just deploy it. After running amplify pull
on my machine, I'm able to leverage the updated data model straight away.
Technologies Under the Hood
The beautiful thing about DataStore is that it's not a separate piece of technology altogether. It's a thoughtfully-built library that leverages all the same technologies we're likely to use in a modern serverless application:
Dynamo
AppSync
IndexedDB
IndexedDB is, of course, used as the local/offline database. All the data is then stored in DynamoDB tables using AppSync GraphQL endpoints.
In principle, you don't need to worry about knowing any of this when using Amplify DataStore. It is all beautifully abstracted away. Some people may of course find the lack of control scary. But it is, after all, part of what we do when we choose to build applications with Serverless.
It's Easy to Get Started
Typically, building or updating my data models involves a clear understanding of access patterns (especially if leveraging Single Table Design), a brief design session on Lucidchart, updating my GraphQL endpoints, and setting up the tables using Infrastructure-as-Code.
These are all valid steps. For big, enterprise-grade applications they may well be the only way. It is certainly how I've built applications using Dynamo and AppSync for several years. I don't intend to move them to Amplify DataStore any time soon.
But there is a whole set of applications that is either too small or, perhaps, too early on in the journey, to justify all that effort. I've argued before that, in such scenarios, worrying about Single-Table Design, microservice architecture, and event-driven patterns is a huge overkill. It's just unnecessary.
Amplify DataStore (and the broader Amplify ecosystem for that matter) makes it super easy to get going quickly.
But It's a Powerhouse Under the Hood
What's incredible about it, though, is that behind the scenes it uses all the same, hyper-scalable serverless technologies we would be using anyway. It's just AppSync and DynamoDB after all. You can't go wrong with that.
Like anyone else who has built massive-scale serverless applications on AWS, I know how insanely powerful DynamoDB is. Knowing that behind the pretty UI and lovely ORM-like code sits good old Dynamo makes me think that an application built with Amplify DataStore can, in principle, be pushed quite hard without sacrificing performance.
Further Optimisation May Require Some Work
In the real world, though, once a certain scale is reached it may be appropriate to start thinking about DynamoDB's best practices for increased performance (such as the aforementioned Single Table Design).
That could prove a little tricky if the entire system has been built using Amplify DataStore. But it wouldn't be unlike a transition from a monolithic to a microservice architecture, which is exactly the type of journey I and others have been advocating for when building serverless applications: start with a monolith-like architecture, and evolve as required by the specific use case.
Final Thoughts
Amplify DataStore is a pleasure to work with, and the overall value proposition is really compelling.
In theory, a large-scale application could outgrow DataStore and need to transition to a more "controllable" and customisable setup.
I'm not convinced, though, that DataStore won't comfortably handle the vast majority of small to medium-scale applications.
This is great news for builders who are keen to get something out there quickly and efficiently!
It could also be the cause of many headaches for cloud architects who need to design future-proof applications and/or manage the transition from medium to large scale.
How does one gain the kind of fine-grained control we’re accustomed to with AppSync and DynamoDB? And, how far can Amplify DataStore be pushed before that type of control is even needed?
Clarifying those points and making it easier to bounce between DataStore and standard AppSync should, in my view, be a top priority for the Amplify team.