CQRS with AWS AppSync

Command Query Responsibility Segregation

Command Query Responsibility Segregation (CQRS) is an architecture pattern found in applications ranging in size from startups to enterprise. At a high level, this pattern separates read and update operations for a datastore. There is plenty of technical writing teaching this pattern in detail (Martin Fowler, Udi Dahan), we’re going to avoid rehashing the work they have already done, I highly suggest reading the two links provided below.

What is not readily available are examples of achieving this architecture with modern cloud services. Even more so, how to do this with limited engineering resources. If you are leading a small engineering team, launching a side project and you are looking to lean on an established highly scalable pattern, CQRS with AppSync might be an interesting option for you.

The technologies we've chosen to use (more on that below) coupled with CQRS has been a force multiplier for my team while scaling

Thoughts & Considerations

My issue with AWS, and generally all cloud providers is that while they provide many different services, and many of them are VERY good, there is no easy “on-ramp” into building on, or architecting an application. Even after attaining cloud certifications, one can remain feeling clueless on how to begin, architect and develop a green field application. This is why Ruby on Rails (RoR), Laravel, Express apps, still thrive in the domain of side projects, startups and even large engineering orgs, they are incredibly quick to start, prototype and release to market.

As with all stack decisions, it comes with a cost, here the cost is complexity. Appsync is a managed graphql service offered by AWS, and in my personal opinion, one of the best services offered by AWS. AppSync integrates with a whole suite of services within AWS, which I believe can make the service harder to grok. When presented with an incredible technology (AppSync) that can interface with almost everything you want to use, a developer can get lost with a paralysis of choice.

AppSync & Amplify

AWS AppSync is a managed graphql service that interfaces with DynamoDb, OpenSearch (ElasticSearch), Lambda, Amazon Aurora, Cloudwatch etc. Amplify is the client SDK that offers a clean API to connect to AppSync, and other AWS services (ML, prediction, text recognition, etc). Some complain about the bundle size of the library, don't be foolish, use the library and move faster with it, speed kills.

DynamoDb

Amazon DynamoDb is a fully managed, serverless, key-value NoSQL database designed to run high-performance applications at any scale. DynamoDb offers built-in security, continuous backups, automated multi-Region replication and in-memory caching.In short, it’s super inexpensive to run, extremely efficient, interfaces nicely with AppSync, and completely managed by AWS, no need to manage upgrades, patches etc. DynamoDb has a learning curve, and to get up the curve, the best resources would be anything Alex Debrie has written, I've personally read his book, and it's a great resource.

OpenSearch

OpenSearch enables you to easily ingest, secure, search, aggregate, view, and analyze data for a number of use cases such as log analytics, application search, enterprise search, and more. OpenSearch is the perfect datastore when searching for text, or geo-location.

Reads, writes and distributed datastores

In a distributed event driven system, keeping data in sync can seem very complex. Given that AppSync is a managed service, it wasn't immediately obvious how to keep OpenSearch/ElasticSearch in sync with DynamoDb. The question I asked myself went something like...

If I am writing to DynamoDb, querying OpenSearch, what happens if I update
an attribute on an item in DynamoDb, how does the item in OpenSearch get
updated and stay in sync with the item in DynamoDb?

Resources

Martin Fowler - CQRS

Udi Dahan - Clarified CQRS