Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

finish overview section #744

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 23 additions & 12 deletions docs/docs/1-getting-started/1-overview/index.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
---
title: Overview 👷
title: Overview
---

# Overview 👷
# Overview

AWS DynamoDB is a [key-value DB designed to run high-performance applications at any scale](https://aws.amazon.com/dynamodb). It automatically scales up and down based on your current traffic, and does not require maintaining connections, which makes it the **go-to DB service for serverless developers on AWS**.
[AWS DynamoDB](https://aws.amazon.com/dynamodb) is a key-value DB 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 for serverless developers**.

AWS published the [document client SDK](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html), to craft said requests. However, if you’ve ever used it, you will know that **it’s still very painful to use**.

Let’s look at this `UpdateCommand` example straight from the [DynamoDB documentation](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.UpdateItem.html):
AWS published the [NodeJS Document Client](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html) to craft said requests. However, if you’ve ever used it, you know that **it’s painful to use**. Take a look at this `UpdateCommand` example straight from the [AWS documentation](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.UpdateItem.html):

```ts
await documentClient.send(
Expand Down Expand Up @@ -37,19 +35,30 @@ await documentClient.send(
)
```

It is a very simple example (updating two fields of a `Movie` item), yet already very cumbersome and verbose 😰
It's a very simple example (updating two fields of a `Movie` item), yet already cumbersome and verbose 😰

**Things only get messier as your data grows in complexity**: 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 one of its attribute (e.g. a `status` attribute)? What about polymorphism?
**Things only get messier as your data grows in complexity**: 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 one of its attribute? What about polymorphism?

In those cases, which are fairly common, **the required code to generate those requests gets very hard to maintain**.

That's when DynamoDB-Toolbox comes to the rescue 💪

- 🏋️‍♀️ It simplifies the writing of DynamoDB requests
- 📐 It adds run-time **data validation**, i.e. **“artificial” schemas** to a schema-less DB (and more recently type-safety)
- Also: Single-table design, transforming of attributes to reduce costs, linking attributes values to project on secondary indexes.
---

<p align="center" style={{ fontSize:'larger' }}>DynamoDB-Toolbox is a <b>light-weight</b> and <b>type-safe</b><br/><b>query builder</b> for DynamoDB and TypeScript.</p>

---

It is an abstraction layer over the Document Client that adds many benefits:

Here is the same `UpdateCommand` with DynamoDB-Toolbox:
- 🤗 **Simpler queries**: DynamoDB-Toolbox does all the heavy-lifting of crafting those **cumbersome DynamoDB requests** and make your code **clearer**, **more succinct** and **easier to maintain**.
- 📐 **Data validation**: Both pushed and fetched items are **validated** against your schemas, which guarantees the **consistency** of your data and the **reliability** of your code.
- ✨ **A rich schema syntax** that supports a broad range of edge cases like **defaults**, **composition**, **transformation** or **polymorphism**
- 🌈 **Type-safety pushed to the limit**: Increase your development velocity with **instantaneous feedbacks** and **slick auto-completion**.
- 🌴 **Tree-shakable**: Only import what you need
- 🥇 **Single-table designs**: DynamoDB-Toolbox makes **querying multiple entities within the same table extremely simple**, although it works just as well with multiple tables.

Here's is a quick preview with the DynamoDB-Toolbox version of the `UpdateCommand` described above:

```ts
// Validated AND type-safe syntax 🙌
Expand All @@ -66,3 +75,5 @@ await MovieEntity.build(UpdateItemCommand)
```

And just like that, we went from an obscure 18-line class to a readable and elegant 10-liner 🤩

Not bad, eh? Let's dive into it!
4 changes: 2 additions & 2 deletions docs/docs/1-getting-started/2-installation/index.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: Installation ⭐️
title: Installation
---

# Installation ⭐️
# Installation

```bash
# npm
Expand Down
20 changes: 11 additions & 9 deletions docs/docs/1-getting-started/3-usage/index.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
title: Usage ⭐️
title: Usage
---

import Mermaid from '@theme/Mermaid';

# Usage ⭐️
# Usage

DynamoDB-Toolbox mainly exposes three classes:

Expand Down Expand Up @@ -85,13 +85,13 @@ const PokemonEntity = new Entity({
})
```

An entity must belong to a Table, but the same Table can contain items from several entities. DynamoDB-Toolbox is designed with **Single Tables** in mind, but works just as well with multiple tables, it'll still make your life much easier (batch gets and writes support multiple tables, so we've got you covered).
An entity must belong to a Table, but the same Table can contain items from several entities. DynamoDB-Toolbox is designed with [Single Tables](https://www.alexdebrie.com/posts/dynamodb-single-table/) in mind, but works just as well with multiple tables, it'll still make your life much easier (batch gets and writes support multiple tables, so we've got you covered).

Once you have defined your `Tables` and `Entities`. You can start using them in combination with **Actions**.

## Methods vs Actions

Queries, updates, transactions, batch operations... DynamoDB has a **wide range of features**. Exposing all of them as distinct methods would **bloat the `Entity` and `Tables` classes**. Class methods are not tree-shakable, and why bother bundling the code needed for a feature (which can be quite large) if you don't need it?
Queries, updates, transactions, batch operations... DynamoDB has a **wide range of features**. Exposing all of them as distinct methods would **bloat the `Entity` and `Table` classes**. Class methods are not tree-shakable, and why bother bundling the code needed for a feature (which can be quite large) if you don't need it?

Instead, `Tables`, `Entities` and `Schemas` have a single `.build` method which is exactly **1-line long** 🤯 and acts as a gateway to perform [Actions](#how-do-actions-work):

Expand All @@ -105,13 +105,13 @@ const { Item } = await PokemonEntity.build(GetItemCommand)

DynamoDB operations like the [GetItemCommand](../../3-entities/2-actions/1-get-item/index.md) are instances of actions, but DynamoDB-Toolbox also exposes utility actions, e.g. for [parsing](../../3-entities/2-actions/16-parse/index.md) and [formatting](../../3-entities/2-actions/19-format/index.md).

The syntax is a bit more verbose that a simple `PokemonEntity.get(key)`, but it allows for **extensibility**, **better code-splitting** and **lighter bundles** (which is key in the Serverless era) while keeping an intuitive **entity-oriented** and **type-inheriting syntax**.
The syntax is a bit more verbose that a simple `PokemonEntity.get(key)`, but it allows for **extensibility**, **better code-splitting** and **lighter bundles** while keeping an intuitive **entity-oriented** and **type-inheriting syntax**.

:::info

Notice how the action is imported through a deep import, thanks to the [`exports`](https://nodejs.org/api/packages.html#subpath-exports) field of the `package.json`, allowing for even better code splitting.
Notice how the action is imported through a deep import, thanks to the [`exports`](https://nodejs.org/api/packages.html#subpath-exports) field of the `package.json`.

Although all classes and actions are exposed in the main entry path, we recommend using subpaths. That's what we'll do in the rest of the documentation.
Although all classes and actions are exposed in the main entry path, we recommend using subpaths, and that's what we'll do in the rest of the documentation.

:::

Expand Down Expand Up @@ -148,13 +148,13 @@ const pokemonEntityName = nameGetter.get()
// => "POKEMON"
```

The `.build` methods simply instanciate a new action with its parent as first constructor parameter. Another way to do it would be:
`PokemonEntity.build` simply instanciates a new action with `PokemonEntity` as the constructor first parameter. Another way to do it would be:

```ts
const nameGetter = new NameGetter(PokemonEntity)
```

Although this action-oriented syntax is (we find) less readable than the entity-oriented one, it leads to exactly the same result: Feel free to use it if you prefer!
Although this action-oriented syntax is (we find) less readable than the entity-oriented one, it leads to exactly the same result, so feel free to use it if you prefer!

Here's a comparison of both syntaxes on the [`GetItemCommand`](/docs/entities/actions/get-item) action:

Expand All @@ -172,3 +172,5 @@ const { Item } = await new GetItemCommand(
{ consistent: true }
).send()
```

<!-- TODO: Add examples next -->
5 changes: 0 additions & 5 deletions docs/docs/1-getting-started/4-examples/1-todo.md

This file was deleted.

5 changes: 0 additions & 5 deletions docs/docs/1-getting-started/4-examples/2-todo-2.md

This file was deleted.

4 changes: 0 additions & 4 deletions docs/docs/1-getting-started/4-examples/_category_.json

This file was deleted.

2 changes: 1 addition & 1 deletion docs/docs/1-getting-started/_category_.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"label": "🚀 Getting Started 👷",
"label": "🚀 Getting Started",
"position": 1
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dynamodb-toolbox",
"description": "A simple set of tools for working with Amazon DynamoDB and the DocumentClient.",
"description": "Light-weight and type-safe query builder for DynamoDB and TypeScript.",
"author": "Jeremy Daly <jeremy@jeremydaly.com>",
"exports": {
".": "./dist/index.js",
Expand Down
Loading