Using TypeScript with Key/Value Databases

Rate this content
Bookmark

Key/value (KV) databases are becoming ever more popular in web applications. Their super-fast response times and ability to support eventual consistency reads make them especially well suited for apps running on globally distributed edge servers. But with how fast this tech is moving, you might not be fully up to speed on how to use this type of database with TypeScript. In this session, we'll explore good use cases for KV databases, examine several production deployment options, and demonstrate how to effectively hydrate TypeScript objects from values in a KV database.

This talk has been presented at TypeScript Congress 2023, check out the latest edition of this JavaScript Conference.

FAQ

To manage complex data structures, key-value databases often use techniques such as hierarchical key structures and secondary indexes to organize data and improve access patterns, though they generally have simpler query capabilities compared to relational databases.

Key-value databases typically prioritize high availability over strict consistency, often operating under eventual consistency models. However, some key-value databases offer configurations for stronger consistency and even support transactional operations depending on the system's capabilities.

Popular key-value databases include Redis, which offers rich command sets and is used extensively for caching and as a primary datastore, and DynamoDB, known for its robust querying capabilities and flexible consistency models. Both databases cater to different needs and scalability requirements.

Key-value databases store data in a non-relational format, primarily as unique key-value pairs, and are optimized for simple query models and high performance. In contrast, relational databases organize data into tables linked by relationships, which supports complex queries and transaction consistency.

Common use cases for key-value databases include storing user preferences, session states like shopping carts, and real-time game states. They are well-suited for scenarios needing quick read and write operations with simple data models.

A key-value database is a type of non-relational database that stores data as a collection of key-value pairs, where a key, which is a unique identifier, is associated directly with a value. This structure allows for efficient data retrieval and is optimized for high availability and partition tolerance.

Kevin Whinnery
Kevin Whinnery
31 min
21 Sep, 2023

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Key-value databases are optimized for high availability and partition tolerance, making them ideal for storing non-relational data structures. They prioritize speed and high availability over consistency, making them suitable for simple data models or one-to-one mappings. However, they have limited query capabilities compared to relational databases. Some available options for key-value databases include DynamoDB, CloudFlare Worker KV, Redis, and FoundationDB. Using key-value databases in TypeScript requires addressing challenges such as serialization, deserialization, secondary indexes, relationships, and validation. The Talk includes a demonstration of an application that showcases the use of secondary indexes and the implementation of a key-value database in Deno or Redis.

1. Introduction to Key-Value Databases

Short description:

In this part, we'll discuss the key characteristics of a KV database, including its ability to store non-relational data structures and its optimization for high availability and partition tolerance. We'll also explore different flavors of KV databases and how to use them in TypeScript applications.

How's it going, folks? My name is Kevin Winery, and today we're going to talk a little bit about key-value databases. And if you've never used a KV database before in the context of a JavaScript web application, I think you're really going to enjoy it and learn how it's a little bit different than some of the other databases you've used before and kind of when you might want to apply this technology in the code that you're already writing.

So in this presentation specifically, we're going to take a look at some of the key characteristics that make a KV database different from a relational database that you might have used in the past. And we'll also examine some of the use cases for which a KV database is uniquely suited and might be the tool that you reach for in those contexts. We'll also look at some of the different KV database options that are out there. There's a number of hosted platforms, vendors, open source projects that make KV databases available. So we'll take a look at some of the different flavors of KV databases that exist and what makes them different. And finally, we'll take a look at how to use a KV database in the context of a TypeScript application, and how to solve some of the common programming challenges you're likely to run into if you are using a KV database.

So let's dive in by talking a little bit about the key characteristics of a KV database. And what it boils down to really is two key things. A KV database is really good at storing non-relational data structures. And it's also sort of optimized to be highly available and partition tolerant. And we'll dive in a little bit more deeply into both of these areas to understand what that means. But we'll start with what I mean when I say non-relational data structures, specifically, and why KV database is optimized for those things. So as a JavaScript developer, a data structure like this is probably something that you've seen before. It's an object literal with keys that map to other object literals that contain data about a user that is within your application, their full name, their email address, and things like that. And KV database actually functions a lot like an object literal or a map from the JavaScript world where you have a key that maps one-to-one to a value in your application of some kind.

2. Key Characteristics and Techniques of KV Databases

Short description:

In this part, we'll discuss the key characteristics of a KV database, including its ability to store non-relational data structures and its optimization for high availability and partition tolerance. We'll also explore different techniques, such as hierarchical data structures and secondary indexes, that can be used to create complex data models within a KV database.

And those values can be arbitrary JavaScript objects structured however you'd like. And the keys, depending on the database that you're using, can either be just a plain string or a key could be like a compound value, like an array that could have multiple different kinds of values that come together to form a unique identifier for one of the values in your database.

Now the key characteristic there, though, is that one-to-one mapping between a key and some kind of value that exists in your database. And the way that you typically interact with a KV database from your code is you'll specify a key, you'll create a value—oftentimes in a TypeScript context there'll be like type information that's associated with that value before it's stripped away at runtime and becomes just a plain JavaScript object. And there's this get set API that's generally going to be available in every database where you can associate some bit of data with a particular key in your database.

And in addition to just having this one-to-one mapping, there's also a couple of techniques that you'll use for more complex data within your application. And one of those things is sort of the concept of a hierarchy that could exist in your application as well. Because a KP database, just by itself, is fairly limited in what it can express in terms of the structure of your data. There's a key, there's a value, that's pretty much it.

And for simpler use cases like storing user preferences or some of the other use cases we'll get into in a minute, that might be fine. But by employing just a couple of different tricks with how you think about your data, you can actually get a lot more value and express a lot more meaning in your key value database by introducing some different techniques in how you manage your key space or the set of keys that you use to map to your data. And one of those things is a hierarchy.

So if you have been in web development for a while, you may have used a RESTful API where this concept of hierarchical data and as you build URLs, you can sort of infer from the structure of the URL how the data that is found at a particular resource might be used within your application. And when you're designing keys for the data in your database, you can actually think about it in a very similar way where you can create a hierarchy of data in how you structure your keys. So you'll see examples here where if you're storing data in a KV database for a blog post, you might structure the key in such a way where there's a post key that's then followed by like a year key and then you can build a key progressively using the different parts of either the slug for the blog post or like the month and the day that it was published. And now you have as a part of your key actually encoded some useful data that you could then later use to maybe grab all the blog posts from a particular year or a particular month. So structuring your data in a hierarchical way gives you a way to add a little bit of extra value and meaning into the keys that you're using for your data.

The other very common technique that you're going to imply in a KV database is this idea of a secondary index. KV databases are non-relational, so you're not going to be storing a join table that's gonna be mapping one record in a data table somewhere to another one. But that doesn't mean that you can't maintain any kind of relationships or have different ways of addressing your data.

So a common need is to be able to access the same type of information by a slightly different key. So let's imagine you have a database of users and the sort of primary key that you use for that is the user's username. That's sort of the primary identifier that you have for them in your system. However, the email address for a user might be another way to uniquely distinguish a user in your application, so you want to be able to address and fetch data for a user based on that as well. So what you would do is, when you would store the information in your KV store under one ID, you would at the same time store that same information under another ID or a secondary index, which would allow you to look up the same information using that secondary index. And typically what you'd do is you'd store that in that secondary index, you would just store whatever the key value is for the primary index and then use that to such that, you know, only one value in your database is sort of the source of truth for the data associated with that record.

So with a combination of hierarchical data structures and secondary indexes, you can actually create pretty complex data models within a KV database. Maybe not at the same level as a relational database, but you'd be surprised how much mileage you can get out of just these two techniques.

So we talked a little bit about a KV database being a non-relational data structure store, let's talk a little bit about some of the technical parts that make it different from a relational database, and specifically about how these types of databases tend to be very highly available and partition-tolerant. And to understand what those words mean, we will take a quick, deep tour to talk about this idea of Cap Theorem.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React's Most Useful Types
React Day Berlin 2023React Day Berlin 2023
21 min
React's Most Useful Types
Top Content
Watch video: React's Most Useful Types
Today's Talk focuses on React's best types and JSX. It covers the types of JSX and React components, including React.fc and React.reactnode. The discussion also explores JSX intrinsic elements and react.component props, highlighting their differences and use cases. The Talk concludes with insights on using React.componentType and passing components, as well as utilizing the react.element ref type for external libraries like React-Select.
TypeScript and React: Secrets of a Happy Marriage
React Advanced 2022React Advanced 2022
21 min
TypeScript and React: Secrets of a Happy Marriage
Top Content
React and TypeScript have a strong relationship, with TypeScript offering benefits like better type checking and contract enforcement. Failing early and failing hard is important in software development to catch errors and debug effectively. TypeScript provides early detection of errors and ensures data accuracy in components and hooks. It offers superior type safety but can become complex as the codebase grows. Using union types in props can resolve errors and address dependencies. Dynamic communication and type contracts can be achieved through generics. Understanding React's built-in types and hooks like useState and useRef is crucial for leveraging their functionality.
Making Magic: Building a TypeScript-First Framework
TypeScript Congress 2023TypeScript Congress 2023
31 min
Making Magic: Building a TypeScript-First Framework
Top Content
Daniel Rowe discusses building a TypeScript-first framework at TypeScript Congress and shares his involvement in various projects. Nuxt is a progressive framework built on Vue.js, aiming to reduce friction and distraction for developers. It leverages TypeScript for inference and aims to be the source of truth for projects. Nuxt provides type safety and extensibility through integration with TypeScript. Migrating to TypeScript offers long-term maintenance benefits and can uncover hidden bugs. Nuxt focuses on improving existing tools and finds inspiration in frameworks like TRPC.
Stop Writing Your Routes
Vue.js London 2023Vue.js London 2023
30 min
Stop Writing Your Routes
Designing APIs is a challenge, and it's important to consider the language used and different versions of the API. API ergonomics focus on ease of use and trade-offs. Routing is a misunderstood aspect of API design, and file-based routing can simplify it. Unplugging View Router provides typed routes and eliminates the need to pass routes when creating the router. Data loading and handling can be improved with data loaders and predictable routes. Handling protected routes and index and ID files are also discussed.
Faster TypeScript builds with --isolatedDeclarations
TypeScript Congress 2023TypeScript Congress 2023
24 min
Faster TypeScript builds with --isolatedDeclarations
Top Content
This talk discusses the performance issues in TypeScript builds and introduces a new feature called isolated declarations. By running the compiler in parallel and using isolated modules, significant performance gains can be achieved. Isolated declarations improve build speed, compatibility with other tools, and require developers to write types in code. This feature has the potential to further increase performance and may be available in TypeScript soon.
Full-stack & typesafe React (+Native) apps with tRPC.io
React Advanced 2021React Advanced 2021
6 min
Full-stack & typesafe React (+Native) apps with tRPC.io
Top Content
Alex introduces tRPC, a toolkit for making end-to-end type-safe APIs easily, with auto-completion of API endpoints and inferred data from backend to frontend. tRPC works the same way in React Native and can be adopted incrementally. The example showcases backend communication with a database using queries and validators, with types inferred to the frontend and data retrieval done using Prisma ORM.

Workshops on related topic

React, TypeScript, and TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
Mastering advanced concepts in TypeScript
React Summit US 2023React Summit US 2023
132 min
Mastering advanced concepts in TypeScript
Top Content
Featured WorkshopFree
Jiri Lojda
Jiri Lojda
TypeScript is not just types and interfaces. Join this workshop to master more advanced features of TypeScript that will make your code bullet-proof. We will cover conditional types and infer notation, template strings and how to map over union types and object/array properties. Each topic will be demonstrated on a sample application that was written with basic types or no types at all and we will together improve the code so you get more familiar with each feature and can bring this new knowledge directly into your projects.
You will learn:- - What are conditional types and infer notation- What are template strings- How to map over union types and object/array properties.
Deep TypeScript Tips & Tricks
Node Congress 2024Node Congress 2024
83 min
Deep TypeScript Tips & Tricks
Top Content
Featured Workshop
Josh Goldberg
Josh Goldberg
TypeScript has a powerful type system with all sorts of fancy features for representing wild and wacky JavaScript states. But the syntax to do so isn't always straightforward, and the error messages aren't always precise in telling you what's wrong. Let's dive into how many of TypeScript's more powerful features really work, what kinds of real-world problems they solve, and how to wrestle the type system into submission so you can write truly excellent TypeScript code.
Best Practices and Advanced TypeScript Tips for React Developers
React Advanced 2022React Advanced 2022
148 min
Best Practices and Advanced TypeScript Tips for React Developers
Top Content
Featured Workshop
Maurice de Beijer
Maurice de Beijer
Are you a React developer trying to get the most benefits from TypeScript? Then this is the workshop for you.In this interactive workshop, we will start at the basics and examine the pros and cons of different ways you can declare React components using TypeScript. After that we will move to more advanced concepts where we will go beyond the strict setting of TypeScript. You will learn when to use types like any, unknown and never. We will explore the use of type predicates, guards and exhaustive checking. You will learn about the built-in mapped types as well as how to create your own new type map utilities. And we will start programming in the TypeScript type system using conditional types and type inferring.
How to Solve Real-World Problems with Remix
Remix Conf Europe 2022Remix Conf Europe 2022
195 min
How to Solve Real-World Problems with Remix
Featured Workshop
Michael Carter
Michael Carter
- Errors? How to render and log your server and client errorsa - When to return errors vs throwb - Setup logging service like Sentry, LogRocket, and Bugsnag- Forms? How to validate and handle multi-page formsa - Use zod to validate form data in your actionb - Step through multi-page forms without losing data- Stuck? How to patch bugs or missing features in Remix so you can move ona - Use patch-package to quickly fix your Remix installb - Show tool for managing multiple patches and cherry-pick open PRs- Users? How to handle multi-tenant apps with Prismaa - Determine tenant by host or by userb - Multiple database or single database/multiple schemasc - Ensures tenant data always separate from others
Building Your Own Custom Type System
React Summit 2024React Summit 2024
38 min
Building Your Own Custom Type System
Featured Workshop
Kunal Dubey
Kunal Dubey
I'll introduce the audience to a concept where they can have end-to-end type systems that helps ensure typesafety across the teams Such a system not only improves communication between teams but also helps teams collaborate effectively and ship way faster than they used to before. By having a custom type system, teams can also identify the errors and modify the API contracts on their IDE, which contributes to a better Developer Experience. The workshop would primarily leverage TS to showcase the concept and use tools like OpenAPI to generate the typesystem on the client side.