Use Arctickey with Next.js for caching, sessions, and real-time features.
Create a Redis client singleton:
// lib/redis.ts import Redis from 'ioredis'; const getRedisClient = () => { return new Redis({ host: process.env.ARCTICKEY_HOST, port: parseInt(process.env.ARCTICKEY_PORT || '6379'), password: process.env.ARCTICKEY_PASSWORD, tls: { rejectUnauthorized: false }, }); }; declare global { var redis: Redis | undefined; } export const redis = globalThis.redis || getRedisClient(); if (process.env.NODE_ENV !== 'production') { globalThis.redis = redis; }
// app/api/products/route.ts import { redis } from '@/lib/redis'; import { NextResponse } from 'next/server'; export async function GET() { const cacheKey = 'products:all'; // Try cache first const cached = await redis.get(cacheKey); if (cached) { return NextResponse.json(JSON.parse(cached)); } // Fetch from database const products = await db.query.products.findMany(); // Cache for 5 minutes await redis.set(cacheKey, JSON.stringify(products), 'EX', 300); return NextResponse.json(products); }
// lib/rate-limit.ts import { redis } from './redis'; export async function rateLimit( identifier: string, limit: number = 10, window: number = 60 ): Promise<{ success: boolean; remaining: number }> { const key = `rate:${identifier}`; const current = await redis.incr(key); if (current === 1) { await redis.expire(key, window); } return { success: current <= limit, remaining: Math.max(0, limit - current), }; }
// app/api/protected/route.ts import { rateLimit } from '@/lib/rate-limit'; import { headers } from 'next/headers'; export async function POST(request: Request) { const ip = headers().get('x-forwarded-for') || 'anonymous'; const { success } = await rateLimit(ip, 10, 60); if (!success) { return new Response('Too many requests', { status: 429 }); } // Handle request... }
// app/actions.ts 'use server'; import { redis } from '@/lib/redis'; import { revalidatePath } from 'next/cache'; export async function incrementCounter() { const count = await redis.incr('global:counter'); revalidatePath('/'); return count; }
Next.js
Use Arctickey with Next.js for caching, sessions, and real-time features.
Setup#
Create a Redis client singleton:
// lib/redis.ts import Redis from 'ioredis'; const getRedisClient = () => { return new Redis({ host: process.env.ARCTICKEY_HOST, port: parseInt(process.env.ARCTICKEY_PORT || '6379'), password: process.env.ARCTICKEY_PASSWORD, tls: { rejectUnauthorized: false }, }); }; declare global { var redis: Redis | undefined; } export const redis = globalThis.redis || getRedisClient(); if (process.env.NODE_ENV !== 'production') { globalThis.redis = redis; }Caching API Responses#
// app/api/products/route.ts import { redis } from '@/lib/redis'; import { NextResponse } from 'next/server'; export async function GET() { const cacheKey = 'products:all'; // Try cache first const cached = await redis.get(cacheKey); if (cached) { return NextResponse.json(JSON.parse(cached)); } // Fetch from database const products = await db.query.products.findMany(); // Cache for 5 minutes await redis.set(cacheKey, JSON.stringify(products), 'EX', 300); return NextResponse.json(products); }Rate Limiting#
// lib/rate-limit.ts import { redis } from './redis'; export async function rateLimit( identifier: string, limit: number = 10, window: number = 60 ): Promise<{ success: boolean; remaining: number }> { const key = `rate:${identifier}`; const current = await redis.incr(key); if (current === 1) { await redis.expire(key, window); } return { success: current <= limit, remaining: Math.max(0, limit - current), }; }// app/api/protected/route.ts import { rateLimit } from '@/lib/rate-limit'; import { headers } from 'next/headers'; export async function POST(request: Request) { const ip = headers().get('x-forwarded-for') || 'anonymous'; const { success } = await rateLimit(ip, 10, 60); if (!success) { return new Response('Too many requests', { status: 429 }); } // Handle request... }Server Actions#
// app/actions.ts 'use server'; import { redis } from '@/lib/redis'; import { revalidatePath } from 'next/cache'; export async function incrementCounter() { const count = await redis.incr('global:counter'); revalidatePath('/'); return count; }