iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
Bash / Node.js · Débutant

Redis

Maîtriser Redis de zéro : types de données, commandes essentielles, expiration, persistance, cas d'usage réels (cache, sessions, files d'attente) et intégration Node.js.

Redis 7Node.jsioredisDocker
01Introduction et installation02Types de données03Commandes essentielles04Expiration et persistance05Cas d'usage pratiques06Intégration Node.js avec ioredis07Déploiement et production
Chapitre 6·30 min

Intégration Node.js avec ioredis

ioredis est le client Redis le plus utilisé pour Node.js. Support complet de l'API Redis, reconnexion automatique, pipelines, Lua scripts, cluster. La bibliothèque officielle (redis) est aussi valide, mais ioredis reste le standard en production.

Installation

npm install ioredis

Connexion de base

lib/redis.ts
import Redis from 'ioredis'
 
const redis = new Redis({
  host: process.env.REDIS_HOST || '127.0.0.1',
  port: Number(process.env.REDIS_PORT) || 6379,
  password: process.env.REDIS_PASSWORD,
  db: 0,                    // base de données (0-15)
  lazyConnect: true,        // ne se connecte qu'au premier usage
  maxRetriesPerRequest: 3,
})
 
redis.on('error', (err) => console.error('Redis error:', err))
redis.on('connect', () => console.log('Redis connected'))
 
export default redis

En Next.js ou autre framework qui recharge les modules en dev, créer le client en singleton :

lib/redis.ts
import Redis from 'ioredis'
 
declare global {
  // eslint-disable-next-line no-var
  var redis: Redis | undefined
}
 
const redis = global.redis ?? new Redis(process.env.REDIS_URL || 'redis://localhost:6379')
 
if (process.env.NODE_ENV !== 'production') {
  global.redis = redis
}
 
export default redis

Opérations de base

import redis from '@/lib/redis'
 
// String
await redis.set('key', 'value')
await redis.set('key', 'value', 'EX', 3600)   // expire dans 1h
const val = await redis.get('key')             // string | null
 
// Incrémenter
await redis.incr('counter')
await redis.incrby('counter', 5)
 
// Hash
await redis.hset('user:42', { name: 'Alice', role: 'admin' })
const name = await redis.hget('user:42', 'name')
const user = await redis.hgetall('user:42')    // Record<string, string>
 
// List
await redis.lpush('queue', JSON.stringify({ task: 'send_email' }))
const task = await redis.rpop('queue')         // string | null
 
// Set
await redis.sadd('tags', 'redis', 'nodejs')
const isMember = await redis.sismember('tags', 'redis')  // 0 | 1
 
// Supprimer
await redis.del('key')
const ttl = await redis.ttl('key')            // -2 si inexistant, -1 si pas d'expiration

Cache avec helper générique

lib/cache.ts
import redis from './redis'
 
export async function cached<T>(
  key: string,
  ttl: number,
  fn: () => Promise<T>
): Promise<T> {
  const cached = await redis.get(key)
  if (cached) return JSON.parse(cached) as T
 
  const result = await fn()
  await redis.set(key, JSON.stringify(result), 'EX', ttl)
  return result
}

Usage :

// Dans une route API Next.js
const articles = await cached(
  'articles:featured',
  300,  // 5 minutes
  () => db.query('SELECT * FROM articles WHERE featured = true')
)

Sessions avec ioredis

lib/session.ts
import redis from './redis'
import { randomBytes } from 'crypto'
 
const SESSION_TTL = 86400  // 24h
 
export async function createSession(userId: number, role: string): Promise<string> {
  const sessionId = randomBytes(32).toString('hex')
  await redis.set(
    `session:${sessionId}`,
    JSON.stringify({ userId, role, createdAt: Date.now() }),
    'EX', SESSION_TTL
  )
  return sessionId
}
 
export async function getSession(sessionId: string) {
  const data = await redis.get(`session:${sessionId}`)
  if (!data) return null
  // Renouveler le TTL (sliding expiration)
  await redis.expire(`session:${sessionId}`, SESSION_TTL)
  return JSON.parse(data)
}
 
export async function deleteSession(sessionId: string): Promise<void> {
  await redis.del(`session:${sessionId}`)
}

Rate Limiting

lib/ratelimit.ts
import redis from './redis'
 
export async function rateLimit(
  identifier: string,
  limit: number,
  windowSeconds: number
): Promise<{ allowed: boolean; remaining: number }> {
  const key = `ratelimit:${identifier}:${Math.floor(Date.now() / (windowSeconds * 1000))}`
 
  const pipeline = redis.pipeline()
  pipeline.incr(key)
  pipeline.expire(key, windowSeconds)
  const results = await pipeline.exec()
 
  const count = (results?.[0]?.[1] as number) ?? 0
  return {
    allowed: count <= limit,
    remaining: Math.max(0, limit - count),
  }
}

Usage dans un middleware Next.js :

middleware.ts
import { rateLimit } from '@/lib/ratelimit'
import { NextRequest, NextResponse } from 'next/server'
 
export async function middleware(req: NextRequest) {
  const ip = req.headers.get('x-forwarded-for') ?? 'unknown'
  const { allowed, remaining } = await rateLimit(ip, 100, 3600)
 
  if (!allowed) {
    return new NextResponse('Too Many Requests', {
      status: 429,
      headers: { 'X-RateLimit-Remaining': '0' },
    })
  }
 
  const res = NextResponse.next()
  res.headers.set('X-RateLimit-Remaining', String(remaining))
  return res
}

Pipeline — grouper les commandes

Les pipelines envoient plusieurs commandes en une seule requête réseau, réduisant la latence de N×RTT à 1×RTT :

const pipeline = redis.pipeline()
pipeline.set('key1', 'val1')
pipeline.set('key2', 'val2')
pipeline.incr('counter')
pipeline.expire('counter', 3600)
 
const results = await pipeline.exec()
// results = [[null, 'OK'], [null, 'OK'], [null, 3], [null, 1]]
// [err, value] pour chaque commande

Le code est en place. Le dernier chapitre couvre le déploiement Docker sécurisé et le monitoring en production.

Précédent
Cas d'usage pratiques
Suivant
Déploiement et production

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main