Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
April 19, 2023 08:24 am GMT

An in-depth comparison of the most popular DynamoDB wrappers

AWS DynamoDB is a key-value database designed to run high-performance applications at any scale. It automatically scales up and down based on your current traffic, and does not require maintaining connections (as requests are sent over HTTP), which makes it the go-to DB service for serverless developers on AWS.

Because its 2023 and no-one writes HTTP requests anymore, AWS published a SDK called the document client to craft said requests. However, if youve ever used it, you will know that its still very painful to use.

For instance, lets look at this UpdateCommand example straight from the DynamoDB docs itself:

await DocumentClient.send(  new UpdateCommand({    TableName: 'TABLE_NAME',    Key: {      //  No type-safety on the primary key      title: 'MOVIE_NAME',      year: 'MOVIE_YEAR',    },    //  String expressions hard to build (and still no type-safety)    UpdateExpression: 'set info.plot = :p, info.#r = :r',    //  When used in Expressions, attribute names have to be provided separately    ExpressionAttributeNames: {      '#r': 'rank',    },    //  List of attribute names as strings separated by commas    ProjectionExpression: '#r',    //  Attribute values have to be provided separately    ExpressionAttributeValues: {      //  No validation or type-safety to enforce DB schema      ':p': 'MOVIE_PLOT',      ':r': 'MOVIE_RANK',    },  }),);

It is a very simple example (updating two fields of a Movie item), yet already very verbose And things only get messier as the complexity of your business logic grows: What if your items have 20 attributes? With some of them deeply nested? Or optional? What if you want to index an item or not depending on its values (e.g. a status attribute)? What about polymorphism?

In those cases (which are quite common) the required code to generate those requests can get very hard to maintain. That is why, very early on, developers built open-source libraries to wrap the DynamoDB client, with two goals in mind:

  • Simplifying the writing of DynamoDB requests
  • Adding run-time data validation, i.e. artificial schemas to a schema-less DB (and more recently type-safety)

For instance, here is an example of the same UpdateCommand with one of those wrappers, DynamoDB-Toolbox:

import { Table, Entity } from 'dynamodb-toolbox';// Provided some schema specifications...const MovieTable = new Table({  name: 'TABLE_NAME',  partitionKey: 'title',  sortKey: 'year',  DocumentClient, // <= the original DocumentClient});const MovieEntity = new Entity({  name: 'Customer',  attributes: {    title: { partitionKey: true, type: 'string' },    year: { sortKey: true, type: 'string' },    info: { type: 'map' },  },  table: MovieTable,} as const);// ...we get a validated AND type-safe request method await MovieEntity.update({  title: 'MOVIE_NAME',  year: 'MOVIE_YEAR',  info: {    plot: 'MOVIE_PLOT',    rank: 'MOVIE_RANK',  },});

And just like that, we went from an obscure 18-line object to a readable and elegant 8-liner Not bad, don't you think?

DynamoDB-Toolbox is not the only SDK wrapper out there. If you browse Alex DeBries awesome-dynamodb-tools repo, youll actually find a bunch of them. So, which one should you chose?

In this article, we took an in depth comparison of the 4 most popular DynamoDB wrappers:

  • Dynamoose: Dynamoose is the OG of DynamoDB wrappers. Created in 2015, it provides a syntax that closely mirrors that of the popular Mongoose library for MongoDB.
  • DynamoDB Toolbox: DynamoDB-Toolbox was created by Jeremy Daly, AWS Serverless Hero, and writer of the newsletter off-by-none. It was first released in September 2018 and has gained in popularity ever since.
  • ElectroDB: Released in April 2020 by Tyler W. Walsh, ElectroDB benefits from having been created after Typescript won over the JS ecosystem. So it has a higher focus on type-safety than its predecessors.
  • DynamoDB-OneTable: First released in January 2021, DynamoDB-OneTable is maintained by Sensedeep and is part of its broader Serverless Developer Studio offer.

We ranked them based on the following criteria:

  • Library state: Classic open-source KPIs such as number of downloads, community, documentation etc.
  • Data modeling: The broadness of their Entity definition API. Do they allow attribute name re-mapping (useful for single-table design)? Do they support enums? Nested attributes definitions? Computing indexes from other attributes?
  • Typescript support: Type-safety is all the rage these days! All libraries come with some sort of type-safety, but type-inference (i.e. inferring tailored types from custom schemas) is still hard to get right.
  • API: How easy it is to do common DynamoDB requests like put, get or query... with secondary indexes, filters and conditions (You can find examples for each wrapper in our dedicated repo).

Library state

(*as of 2023/02)DynamooseDynamoDB-Toolbox ElectroDBDynamoDB-OneTable
First release date2014-02-272019-11-202020-03-112021-01-12
Last release dateJan. 6, 2023Jan. 8, 2023Jan. 20, 2023Jan. 25, 2023
Github 19001400530505
NPM weekly downloads86 k38 k4 k16 k
Bundle size382 kB64.1 kB176.7 kB64.3 kB
DocumentationNo global searchCan be improved
DynamoDB Client v3 compatibility

All four libraries are well maintained, and have enough GitHub stars and npm downloads to be considered battle tested.

Dynamoose has the highest stats (probably from being the first one around). However, its the heaviest, with a size of 382KB, which is not negligible, considering that bundles above 5MB negatively impact Lambdas cold starts.

DynamoDB Wrappers Stars History

The main takeaways are that DynamoDB-Toolbox is not compatible with the V3 of the DynamoDB client (though it should be coming soon), and that the DynamoDB-OneTable documentation leaves to be desired.

Data modeling

We initially started with a very broad scope of features useful for Entity definition (like specifying attributes as required, or aliasing attributes). However, most of them were already implemented by all libraries. For the sake of simplicity, we removed them and kept the following ones:

  • Nested attributes definition: Could we type nested fields of lists and maps attributes (like plot and rank in our first Movie example)?
  • Enum support: Could we specify a finite range of values for a primitive attribute?
  • Default values: Could we provide default values for an attribute? That is especially useful for entities with simple access patterns like fixed strings. We differentiated independent defaults (fixed or derived from context such as timestamps or env variables) from dependent defaults (computed from other attributes).
  • Pre-save/post-fetch attribute transformation: This can be needed for technical reasons, such as prefixing attributes. When possible, its best to hide such details from your code and let your wrapper handle the heavy-lifting.
  • Polymorphism support: Sometimes, items can switch between different statuses and shapes that go with them. We tested how easy it was to translate to in each library.
DynamooseDynamoDB-Toolbox ElectroDBDynamoDB-OneTable
Nested attributes definition
Enum support
Independent defaults
Dependent defaults Via the set optionVia string templates like "user#${email}"
Attribute value transformation
Polymorphism

Overall, Dynamoose and ElectroDB have the upper hand, with ElectroDB being slightly ahead as it allows deriving attributes default values from other attributes.

Surprisingly, none of those libraries handles polymorphism and type-safe dependent defaults. As a maintainer of DynamoDB-Toolbox, I know for sure that those features are coming in the next major, so if youre already using it, do not consider migrating to ElectroDB just yet

Typescript support

All libraries support Typescript at a basic level, so we mostly focused on type inference. We looked for type inference in:

  • DynamoDB requests: Root and nested level attributes
  • Dependent defaults definition
  • Expressions: Conditions, filters and projections
DynamooseDynamoDB-Toolbox ElectroDBDynamoDB-OneTable
Requests (Root attributes)
Requests (Nested attributes)
Dependent defaults
Expressionsyes but only at root levelVia string templates like "(${role} = {admin})"
IDE performancesSlow

Once again ElectroDB has the upper hand here. Very nice job, Tyler W. Walsh

API

Finally we compared the APIs of each solution for sending DynamoDB requests, i.e. how easy they were to write and understand (verbosity, complexity etc).

  • Single Item Requests: For usual PUT, GET and DELETE requests.
  • Updates: For UPDATE requests. We tested updating nested fields, adding values to numbers and elements to lists.
  • Queries: For querying and using secondary indexes.
  • Conditions & filters: For conditioned write operations and filtered query results.
DynamooseDynamoDB-Toolbox ElectroDBDynamoDB-OneTable
Single Item Requests Clunky Hard to override an existing item (PUT)
Updates Clunky Operations ($delete, $add...) mixed with attributes Operations (delete, add...) are far from attributes (in options)
Queries Uses only FilterExpression Confusing query formalism
Conditions & filters Verbose, ORM-ish Confusing OR clauses Easy to use but incomplete (e.g. AND/OR clauses) String template

If the previous section wasn't enough, this one should convince you NOT to use Dynamoose: I found it hard to believe, but it doesn't even support basic (efficient) queries, and uses only filter expressions under the hood .

That being said, ElectroDB has a the nicest API. I especially liked the possibility to name queries according to their business meaning, but not the find and match methods, which are not native DynamoDB requests and can build costly and inefficient scan requests without you being aware.

Conclusion

Overall, as of march 2023, ElectroDB looks like the best DynamoDB client wrapper. Although it is newer and less battle tested, it is better than its concurrent on every other criteria: It has the same data modeling features, a more complete type inference, and a nicer API.

Nevertheless, there are some parts that could be improved:

  • Type inference still has some blind spots
  • There's no support for polymorphism
  • Entity definition autocompletion could be more helpful (it would benefit from a zod-like approach)

Finally, I would not rule out DynamoDB-Toolbox just yet! Its next major is just around the corner, with many new capabilities that even ElectroDB doesnt have (such as type-safe dependent defaults and polymorphism). So expect a round 2 of this article in the next few months


Original Link: https://dev.to/kumo/an-in-depth-comparison-of-the-most-popular-dynamodb-wrappers-4bog

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To