DEV Community

Cover image for How to easily deal with domain object in Redis
Jordan Soo Yen Yih
Jordan Soo Yen Yih

Posted on

How to easily deal with domain object in Redis

Redis, is a mega fast๐Ÿš€ Open Source in-memory database often used as a cache and to make traditional databases faster. However, most of the developers don't know that redis can also be used as a primary app database. Thanks to a suite of modules that add additional data structures and commands to core redis. Check out the redis modules here.

At the end of 2021, Redis announced a preview release of a new high-level client libraries for Redis, called Redis OM๐ŸŽ‰. The main goal is to make developers as easy as possible to use Redis and the Redis modules. Currently it supports for .NET, Node.js, Python, and Java (Spring).

Today, I would like to share about how to use Redis OM in Nodejs.

Installation โœจ

npm install --save redis-om
Enter fullscreen mode Exit fullscreen mode

After install, we can import the redis-om in our Node.js project.

import { Client, Entity, Repository, Schema } from "redis-om"
Enter fullscreen mode Exit fullscreen mode

These are the 4 classes that we will deal a lot.

Client Usage ๐Ÿค

Client is the main entry point for interacting with Redis. First we initialize a client. Then to connect to our Redis database, we call client open followed by our Redis url.

const client = new Client();

await client.open("redis://<YOUR_REDIS_HOST>:<YOUR_REDIS_PORT>");
Enter fullscreen mode Exit fullscreen mode

If we didn't provide the connection string, by default it uses localhost:6379

Now we ready to talk to redis with the client. Underlying, Redis OM will automatically helps us to serialize and deserialize our structures to redis.

However, we still can run basic Redis commands. For example if we want to clean the redis instance, we can use the execute method to run our Redis command:

await client.execute(['FLUSHALL']);
Enter fullscreen mode Exit fullscreen mode

To close the redis connection, simply call close method with the client instance.

await client.close();
Enter fullscreen mode Exit fullscreen mode

Entity Usage ๐Ÿ‘ฎโ€โ™‚๏ธ

We can define an entity for our data with the Entity class. An entity is basically like a database table. For example we can define a class such as Person or Animal, then extend it with Entity class.

class Person extends Entity {
  get dateAsISO() { return new Date(this.date).toISOString() }
}
Enter fullscreen mode Exit fullscreen mode

Inside the class, we can define some custom functions based on use cases. For example we can define a function to convert our data date field to ISO. It is sort of like computed fields we can use after we fetched our data.

Schema Usage ๐Ÿ“œ

After we created an entity, we can give it a schema that contains a variety of different properties each with it own data type.

let schema = new Schema(
   Person,
   {
      name: { type: "string" },
      age: { type: "number" },
      gender: { type: "string" },
      createdAt: { type: "number" }
   },
   {
      dataStructure: "JSON"
   }
)
Enter fullscreen mode Exit fullscreen mode

By default, the data represents a hash in the redis database. To use the RedisJSON module, add an object with key dataStructure and value JSON in the third parameter when initializing the schema.

Repository Usage ๐Ÿ› 

Repository is the one for us to perform Create, Read, Update, and Delete. To create a repository, we need to pass in the schema and the client we created earlier.

const repository = new Repository(schema, client);
Enter fullscreen mode Exit fullscreen mode

Create New Data โž•

To create a new data, we can use createEntity method and pass in a javascript object.

const data = { name: "John Doe", age: 20, gender: "male", createdAt: Date.now() };

const person = repository.createEntity(data);
Enter fullscreen mode Exit fullscreen mode

Then we can call save method with the person data to commit into the database and redis will return an automatically generated unique id. Redis OM is using ULIDs (Universally Unique Lexicographically Sortable Identifiers). You can think of a ULID as a kind of user-friendly UUID. ULIDs are sortable, globally unique, URL-safe, and fairly human-readable when base32-encoded.

const id = await repository.save();

console.info(`ID : ${id}`);

// ID : 01ARZ3NDEKTSV4RRFFQ69G5FAV
Enter fullscreen mode Exit fullscreen mode

Read Data ๐Ÿ‘€

We can read the data with fetch method.

const person = await repository.fetch(id);
Enter fullscreen mode Exit fullscreen mode

Create Index ๐Ÿ“

Before we search our data, we need to create an index for our data. we can call createIndex method with the repository.

// Create Index
await repository.createIndex();

// Drop Index
await repository.dropIndex();
Enter fullscreen mode Exit fullscreen mode

Search Data ๐Ÿ”

Using RediSearch with Redis OM is where the power of this fully armed and operational battle station starts to become apparent. If you have RediSearch installed on your Redis server you can use the search capabilities of Redis OM. This enables commands like:

const oneDay = Date.now() - 24 * 60 * 60 * 1000;

let persons = await repository.search()
  .where('createdAt').is.greaterThan(oneDay)
  .and('name').matches('john')
  .and('age').equals(20).return.all();
Enter fullscreen mode Exit fullscreen mode

Remove Data ๐Ÿ—‘

await repository.remove(id);
Enter fullscreen mode Exit fullscreen mode

That's it

Now we can easily create a CRUD application with Redis. Do checkout the redis-om-node Github too for more detail on how to use Redis OM in Node.js.

Top comments (0)