Deno KV is a new key-value storage system released with version 1.32 of the Deno runtime. It allows for persistent data storage - meaning that the data is stored on disk between system reboots, and is designed to be very fast and optimized.
At the time of writing, this is still experimental and the API is subject to change. It is therefore recommened to keep data backed up, as is always advisable.
Table of Contents
Overview
Because of Deno KV being experimental, it is only accessable by using the --unstable flag.
It can be accessed through the Deno.KV API. The API is simple, and concists of the following main methods:
- const kv = Deno.OpenKv() - Returns a new instance of the Deno KV object.
- kv.set(key, val) - Allows you set a value at the specified key.
- kv.get(key) - Allows you to get the value associated with the specified key.
- kv.delete(key) - Delete the specified key from the Database.
- kv.list(selector) - Receives a list of items matching the selector.
- kv.atomic() - Allows you to chain multiple methods to be saved on the datastore all in one go.
- kv.close() - Close the the database connection, which will prevent any further operatings from taking place and cancelling currently running operations.
There are also other more specialiced API methods which are beyond the scope of this article. Please refer to the docs for more info.
The keys in the key-value store are javascript types which means they can be strings, numbers or booleans. The values can be arrays, objects or other javascript primitive types.
Example of a simple KV application
Here is a simple example that shows how to use the API. In this example we add a couple of users to a database.
const kv = await Deno.openKv(); // Create a new instance of the object.
kv.set(["users", "jim"], "Jim"); // Sets the key "jim" with the prefix "users"
kv.set(["users", "peter"], "Peter"); // Sets the key "peter" with the prefix "users"
// Receives a list of all keys with "prefix" users.
for await (const res of kv.list({prefix: ["users"]})) {
console.log(res.key);
}
What confused me at first about the kv.set() method is that it does not accept a string as its argument, but instead expects an array as an argument.
Altough this might seem weird at first, it allows for a powerful way to categorize and query data. For example when using the kv.list() we can query data with a prefix or a range selector.
More advanced example
The simple example above shows the prefix selector, but it also support the range selector, which is used in a similar fashion:
kv.list({start: ["users", "j"], end: ["users", "p"]});
Atomic operations
Atomic operations are a powerful way to combine multiple methods in one go. This can improve performance by letting the system combine operations. The order of which you call methods on an atomic operation is guaranteed to be executed in the same order.
The Deno.AtomicOperation object also contains a number of unique and useful methods:
- check()
- commit()
- delete()
- enqueue()
- max()
- min()
- mutate()
- set()
- sum()
You can read more on what these atomic methods does in the Deno API Docs.
Here is a simple example showing the use of Atomic:
kv.atomic().set(key, value).delete(["users", "peter"]).commit();
Getting access to Deno Deploy KV beta
** This is only applicable to those who wants to run Deno KV on Deno Deploy **
At the time of writing Deno Deploy KV is currently only available as a closed beta.
You can join the waitlist by visiting this link: https://deno.com/kv
Once you have access you will see a new tab called "KV (beta)" in your Deno Deploy project dash.
Conclusion
The Deno Key-value storage API is useful and it´s nice to have it integrated into the language, and that it requires no configuration. My only gripe with it is that it is too simple for advanced querying, altough that might not be negative if that´s all you need. If you require more advanced querying I would recommend MySQL or MongoDB.
Additional Resources
https://deno.land/manual/runtime/kv