architecture2025-03-12·8 min·155/348

Vercel Edge Config 활용

Vercel Edge Config를 사용하여 글로벌 설정을 관리하는 방법을 알아봅니다.

Vercel Edge Config 활용

Introduction

Vercel Edge Config는 글로벌 설정을 빠르게 관리할 수 있는 서비스입니다. 기능 플래그, A/B 테스팅, 설정 값을 Edge에서 즉시 확인할 수 있습니다. 이 글에서는 Edge Config를 활용하는 방법을 알아보겠습니다.

Environment

  • Vercel 프로젝트 (Next.js 14+)
  • Edge Runtime
  • Vercel Edge Config
  • TypeScript

Problem

전통적인 설정 관리의 문제점:

// 환경 변수로 설정 관리 시
// 변경 시 재배포 필요
const config = {
  featureA: process.env.FEATURE_A === 'true', // 변경 시 재배포 필요
  maxItems: parseInt(process.env.MAX_ITEMS),  // 변경 시 재배포 필요
};

// 설정 변경이 즉시 반영되지 않음

Analysis

Edge Config의 장점:

  1. 즉시 반영: 설정 변경 시 즉시 적용
  2. 글로벌 배포: 전 세계 Edge 노드에서 빠른 접근
  3. 무상태: 서버리스 함수와 호환
  4. 무료 체험: 소규모 사용 무료

Solution

1. Edge Config 설치 및 설정

npm install @vercel/edge-config
// .env.local
EDGE_CONFIG_ID=your-edge-config-id
EDGE_CONFIG=read-only-token

2. Edge Config 클라이언트 생성

// lib/edge-config.js
import { createClient } from '@vercel/edge-config';

export function getEdgeConfig() {
  return createClient(`${process.env.EDGE_CONFIG}`);
}

3. 기능 플래그 구현

// lib/feature-flags.js
import { getEdgeConfig } from './edge-config';

export async function isFeatureEnabled(featureName) {
  try {
    const edgeConfig = getEdgeConfig();
    const features = await edgeConfig.get('features');
    
    return features?.[featureName] ?? false;
  } catch (error) {
    console.error('Failed to check feature flag:', error);
    return false;
  }
}

// 사용 예시
export async function showNewDashboard() {
  return await isFeatureEnabled('newDashboard');
}

4. A/B 테스팅 구현

// lib/ab-testing.js
import { getEdgeConfig } from './edge-config';
import { cookies } from 'next/headers';

export async function getVariant(testName) {
  const cookieStore = cookies();
  const visitorId = cookieStore.get('visitor_id')?.value || crypto.randomUUID();
  
  try {
    const edgeConfig = getEdgeConfig();
    const tests = await edgeConfig.get('ab-tests');
    
    const test = tests?.[testName];
    if (!test) return 'control';
    
    // 해시 기반 할당
    const hash = hashString(`${testName}-${visitorId}`);
    const bucket = hash % 100;
    
    if (bucket < test.trafficA) return 'variantA';
    if (bucket < test.trafficA + test.trafficB) return 'variantB';
    return 'control';
  } catch (error) {
    console.error('Failed to get A/B test variant:', error);
    return 'control';
  }
}

function hashString(str) {
  let hash = 0;
  for (let i = 0; i < str.length; i++) {
    const char = str.charCodeAt(i);
    hash = ((hash << 5) - hash) + char;
    hash |= 0;
  }
  return Math.abs(hash);
}

5. 동적 설정 관리

// lib/dynamic-config.js
import { getEdgeConfig } from './edge-config';

export async function getConfig() {
  try {
    const edgeConfig = getEdgeConfig();
    
    const [features, limits, messages] = await Promise.all([
      edgeConfig.get('features'),
      edgeConfig.get('limits'),
      edgeConfig.get('messages'),
    ]);
    
    return {
      features: features || {},
      limits: limits || { maxUploads: 10, maxFileSize: 5 * 1024 * 1024 },
      messages: messages || { welcome: 'Hello!' },
    };
  } catch (error) {
    console.error('Failed to load config:', error);
    return getDefaultConfig();
  }
}

function getDefaultConfig() {
  return {
    features: { newDashboard: false },
    limits: { maxUploads: 10, maxFileSize: 5 * 1024 * 1024 },
    messages: { welcome: 'Hello!' },
  };
}

6. 설정 업데이트 (Vercel CLI)

# Edge Config 항목 추가
vercel edge-config add features --data '{"newDashboard": true}'

# Edge Config 항목 업데이트
vercel edge-config update features --data '{"newDashboard": false}'

# Edge Config 항목 삭제
vercel edge-config remove features

7. 미들웨어에서의 사용

// middleware.js
import { NextResponse } from 'next/server';
import { getEdgeConfig } from '@/lib/edge-config';

export async function middleware(request) {
  const edgeConfig = getEdgeConfig();
  const maintenance = await edgeConfig.get('maintenance');
  
  if (maintenance?.enabled) {
    return NextResponse.redirect(new URL('/maintenance', request.url));
  }
  
  return NextResponse.next();
}

8. Edge Config 변경 모니터링

// lib/edge-config-monitor.js
import { getEdgeConfig } from './edge-config';

export function watchConfigChanges(callback) {
  const edgeConfig = getEdgeConfig();
  
  // Edge Config 변경 감지 (Webhook 사용)
  return async function handleWebhook(event) {
    const { type, items } = event;
    
    if (type === 'edge-config.updated') {
      console.log('Edge Config updated:', items);
      await callback(items);
    }
  };
}

Lessons Learned

  1. 즉시 반영: Edge Config는 설정 변경 시 즉시 반영되어 재배포가 불필요합니다.
  2. 기능 플래그: 기능 플래그를 사용하면 안전하게 기능을 출시할 수 있습니다.
  3. A/B 테스팅: Edge Config를 사용하면 손쉽게 A/B 테스팅을 구현할 수 있습니다.
  4. Fallback 전략: Edge Config 접근 실패 시 기본값을 반환하도록 설정해야 합니다.
  5. 보안 고려: Edge Config에 민감한 정보를 저장하지 않아야 합니다.

This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.