If you come from the NestJS world, you love decorators, dependency injection, and strong typing. But when it comes to integrating Redis, it often feels like we're stepping back 10 years: magic strings, manual JSON parsers, and low-level commands that clutter our business logic.
Today I want to introduce nestjs-redisom, an open-source library designed to bridge that gap and treat Redis with the respect it deserves in a modern enterprise architecture.
đ€ Why did I create this?
Redis has evolved. It is no longer just a key-value cache. With Redis Stack (RedisJSON + RediSearch), it has become an incredibly powerful real-time document database.
However, using these features from Node.js is often verbose. Redis OM (the official library) helps, but integrating it into NestJS required a lot of boilerplate. nestjs-redisom removes that friction, giving you a native experience.
Installation
npm install nestjs-redisom redis-om redis
đ ïž Deep Dive into the Code
Let's look at more realistic examples of what you can achieve.
1. Complex Data Modeling (Nested)
We aren't limited to flat strings. We can model complex objects with implicit validation.
// 1. Define a Nested Class
export class Address {
@Prop({ indexed: true })
city: string; // Indexed to search "Users in Madrid"
@Prop()
zipCode: string;
}
// 2. Define the Main Entity
@Schema()
export class UserProfile extends BaseEntity {
@Prop({ textSearch: true })
bio: string;
@Prop({ type: () => Address }) // Nested mapping
address: Address;
@Prop()
roles: string[]; // Array of strings
}
2. Advanced Searching (Fluent API)
This is where nestjs-redisom shines. Forget about learning RediSearch command syntax (FT.SEARCH index "@field:value ..."). Use this fluent, typed API.
"Find users living in 'New York', having the role 'admin', and whose bio mentions 'typescript'"
const users = await userRepo.search()
.where('address_city').equals('New York') // Search in nested object
.and('roles').contain('admin') // Search in Array
.and('bio').matches('typescript') // Full-Text Search
.return.page(0, 10); // Native pagination
3. Document Expiration (TTL)
Handling sessions or temporary cache is trivial. You don't need Lua scripts or anything like that.
// Create a session and make it expire in 1 hour
async createSession(user: User) {
const session = await this.sessionRepo.save(user);
await this.sessionRepo.expire(session[this.sessionRepo.schema.idField], 3600);
return session;
}
đŻ Best Use Cases
- High-Speed Objects: Shopping Carts, Player Profiles, Sessions. Data you read/write 1000 times per second.
-
Powered-Up Cache: Sometimes you need to invalidate cache by criteria ("clear cache for all products in category X"). With standard Redis, this is impossible (or slow with
KEYS *). With RedisOM, it's an O(1) or O(N log N) query. - Geo-Spatial Features: "Find drivers near me", using Redis native power for geo-hashing.
â ïž Trade-offs (Honesty First)
- RAM is Money: Redis stores everything in memory. Don't use this to store 5 years of audit logs.
- Eventual Consistency: Search indexes update asynchronously (milliseconds). It is not strict ACID for immediate post-write searches.
đ Special Acknowledgments
This project has been built with many hours of dedication and love for code.
To a girl who always inspires me in silence, and whose mere existence incentivizes me to keep programming in my free time, thank you "YLP".
đ Try it and Contribute
- Repo: github.com/Alpha018/nestjs-redisom
- Author: dev.to/alpha018
What do you think? Will you give Redis a chance as a document database? đ
Top comments (0)