Work in progress.
- In-memory DynamoDB to be used in unit testing, without needing to spin up dynamodb-local in a docker container. This makes unit tests and integration tests separated only by a single dependency injection. This allows you to write the same tests for both. This gives you the speed of unit tests and the robustness of integration tests, which speeds up the debugging and testing of your core business logic significantly. There is no existing alternative currently for Go. The only library I know of is Dynalite, but it's written in Typescript.
- A DynamoDB expression parser and AST that the in-memory db relies on.
- A DynamoDB API wrapper that I find easier to understand and work with.
bezos is an SDK for reliable cloud backends in AWS. It's an opinionated attempt at making cloud codebases more readable and less error prone. The core idea is that standards & best practices are best enforced by someone writing an SDK or tooling for them. The hope is that by doing so it becomes easier to do the right thing than the wrong thing, thus nudging the entropy of the codebase toward a better state. Hence the philosophy of this framework is that developers should still have the freedom to do the 'wrong' thing, but should be aptly warned and therefore prompted to take the correct precautions.
Another core idea is that we can reduce runtime errors by introducing more types. Similar to how Typescript gives a better experience for Javascript by adding a type definition + compile step, adding a specification + code-generation step to Go can give a better developer experience by autogenerating typed SDKs tailored to your system's infrastructure. The simple act of writing down what your application does & looks like unlocks endless potential for code generation of useful artifacts. The goal is for this "application specification" to grow naturally as we introduce more and more plugins for it.
The benefit of a single SDK is that all services using it will get the benefit of updates with just a single version bump. This is compared to manual edits of every single service. A single SDK thus simplifies or removes the need for certain migrations across repos.
- A better dynamodb library. At the core of an AWS backend's state management is usually DynamoDB, but every repository does DynamoDB in their own way, and at the end of the day AWS SDK is a fairly low level SDK. There's a clear need for:
- Easier local testing. What if unit tests and integration tests were one dependency injection away from being identical?
- Enforcing every entity's invariants to be validated before being committed, forcing the developer to think about them and write them in the first place.
- Reducing boilerplate code. Everyone rewrites the same low-level DynamoDB query and transaction logic.
- Making some DynamoDB concepts and choices clearer.
- Preventing developer mistakes around idempotency and consistency.
- Better standards on how to do "single table design", how to manage all your entities within this single table.
- A quick way to get an overview of what entities are even being stored in your tables.
- A quick way to see what domain events/commands lead to an entity being updated. It's common to have to inspect every method in the service to see whether a certain primary-key is being updated or not.
- Making it easy to do event sourcing. Event sourcing comes with a lot of benefits such as:
- A more testable codebase
- A more maintainable database (recalculating derived state is easy)
- A more observable system because
- You require all lifecycle events to exist. They don't always. Developers are allowed to perform operations without emitting events, which makes some operations hidden to anyone that doesn't look at logs.
- Events will by definition have all the information necessary to reconstruct the data (event sourcing)
- Lots more code generation, for example:
- Autogenerating DBT files that are tied to your actual entities, to enrich your data catalog.
- CLI: A cookie cutter method for the entire project structure in order to enforce a standard project layout for Clean Code / Hexagonal architecture. Every component that is added, such as an external adapter or a piece of new infrastructure, should be done via a CLI that sets up the standard boilerplate code that allows the developer to focus on the crucial business logic or the simple glue.
- Autogenerated libraries/artifacts connected with your CDK infrastructure such that the code doesn't rely on error prone custom environment variables to instantiate clients.
- Enforcing a single-responsibility principle for Lambdas by limiting the types of dependencies that you can pass.