Advanced

Redis dengan Claude Code

Pelajari tentang redis menggunakan Claude Code. Dilengkapi tips praktis dan contoh kode.

penting性 Redis cache

Redis インメモリデータstore sebagai 、cache、sessionmanajemen、リアルタイムpemrosesan 広く使われてい.Claude Code 使えば、tepatなcache戦略 設計しefisien implementasi bisa dilakukan.

dasar的なcache層

import { Redis } from "ioredis";

const redis = new Redis(process.env.REDIS_URL!);

class CacheService {
  private redis: Redis;
  private defaultTTL: number;

  constructor(redis: Redis, defaultTTL = 300) {
    this.redis = redis;
    this.defaultTTL = defaultTTL;
  }

  async get<T>(key: string): Promise<T | null> {
    const data = await this.redis.get(key);
    if (!data) return null;

    try {
      return JSON.parse(data) as T;
    } catch {
      return null;
    }
  }

  async set<T>(key: string, value: T, ttl?: number): Promise<void> {
    const serialized = JSON.stringify(value);
    await this.redis.set(key, serialized, "EX", ttl ?? this.defaultTTL);
  }

  async delete(key: string): Promise<void> {
    await this.redis.del(key);
  }

  async deletePattern(pattern: string): Promise<void> {
    const keys = await this.redis.keys(pattern);
    if (keys.length > 0) {
      await this.redis.del(...keys);
    }
  }
}

const cache = new CacheService(redis);

Cache-Aside pola

async function getPostById(id: string): Promise<Post | null> {
  const cacheKey = `post:${id}`;

  // 1. cacheからpengambilan
  const cached = await cache.get<Post>(cacheKey);
  if (cached) {
    return cached;
  }

  // 2. DBからpengambilan
  const post = await prisma.post.findUnique({
    where: { id },
    include: { author: true, categories: true },
  });

  if (!post) return null;

  // 3. cache penyimpanan(5分)
  await cache.set(cacheKey, post, 300);

  return post;
}

// pembaruan時 cache無効化
async function updatePost(id: string, data: Partial<Post>) {
  const updated = await prisma.post.update({
    where: { id },
    data,
  });

  // 関連cache 無効化
  await cache.delete(`post:${id}`);
  await cache.deletePattern("posts:list:*");

  return updated;
}

cache リスト結果

async function getPostsList(params: {
  page: number;
  category?: string;
}): Promise<PaginatedResult<Post>> {
  const cacheKey = `posts:list:${params.page}:${params.category || "all"}`;

  const cached = await cache.get<PaginatedResult<Post>>(cacheKey);
  if (cached) return cached;

  const result = await fetchPostsFromDB(params);

  // リスト結果 短め TTL(1分)
  await cache.set(cacheKey, result, 60);

  return result;
}

cacheデコレータ

function Cacheable(ttl: number = 300) {
  return function (
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor
  ) {
    const originalMethod = descriptor.value;

    descriptor.value = async function (...args: any[]) {
      const cacheKey = `${target.constructor.name}:${propertyKey}:${JSON.stringify(args)}`;

      const cached = await cache.get(cacheKey);
      if (cached) return cached;

      const result = await originalMethod.apply(this, args);
      await cache.set(cacheKey, result, ttl);

      return result;
    };

    return descriptor;
  };
}

class PostService {
  @Cacheable(300)
  async getById(id: string) {
    return prisma.post.findUnique({ where: { id } });
  }

  @Cacheable(60)
  async getPopular(limit: number = 10) {
    return prisma.post.findMany({
      where: { published: true },
      orderBy: { viewCount: "desc" },
      take: limit,
    });
  }
}

sessionmanajemen

import session from "express-session";
import RedisStore from "connect-redis";

const redisStore = new RedisStore({
  client: redis,
  prefix: "sess:",
  ttl: 86400, // 24時間
});

app.use(
  session({
    store: redisStore,
    secret: process.env.SESSION_SECRET!,
    resave: false,
    saveUninitialized: false,
    cookie: {
      secure: process.env.NODE_ENV === "production",
      httpOnly: true,
      maxAge: 86400 * 1000,
      sameSite: "strict",
    },
  })
);

レート制限

async function rateLimiter(
  key: string,
  maxRequests: number,
  windowSeconds: number
): Promise<{ allowed: boolean; remaining: number; resetAt: number }> {
  const now = Math.floor(Date.now() / 1000);
  const windowKey = `ratelimit:${key}:${Math.floor(now / windowSeconds)}`;

  const current = await redis.incr(windowKey);

  if (current === 1) {
    await redis.expire(windowKey, windowSeconds);
  }

  const remaining = Math.max(0, maxRequests - current);
  const resetAt = (Math.floor(now / windowSeconds) + 1) * windowSeconds;

  return {
    allowed: current <= maxRequests,
    remaining,
    resetAt,
  };
}

// middleware dan penggunaan
async function rateLimitMiddleware(
  req: express.Request,
  res: express.Response,
  next: express.NextFunction
) {
  const key = req.ip || "unknown";
  const result = await rateLimiter(key, 100, 60);

  res.set("X-RateLimit-Remaining", String(result.remaining));
  res.set("X-RateLimit-Reset", String(result.resetAt));

  if (!result.allowed) {
    return res.status(429).json({ error: "Too many requests" });
  }

  next();
}

Pemanfaatan dengan Claude Code

Rediscache implementasi Claude Code 依頼 例.エッジ cache mengenai エッジコンピューティング、非同期pemrosesan ジョブキュー・非同期pemrosesan juga bisa dijadikan referensi.

Rediscache層 設計して。
- Cache-Asidepola dengan 読み取りcache
- pembaruan時 cache無効化戦略
- APIレート制限
- sessionmanajemen
- cache ヒット率monitoring

Redis 詳細 Redis公式dokumen silakan lihat.Claude Code 使い方 公式dokumen konfirmasi bisa dilakukan.

Summary

Rediscache aplikasi performa 劇的 向上させ.Claude Code 使えば、cache戦略 設計 dari 無効化pola implementasiま 、一貫 cache層 pembangunan bisa dilakukan.

#Claude Code #Redis #caching #performance #backend