Buduj API Gateway
Stwórz zunifikowaną bramę API dla wszystkich integracji
Twoja firma potrzebuje integracji z Stripe do płatności, SendGrid do e-maili i Twilio do powiadomień SMS. Poprzedni programista rozpoczął pracę, ale zostawił niekompletny kod bez dokumentacji. Musisz zbudować zunifikowany system powiadomień, który obsługuje płatności, wysyła rachunki e-mailem i powiadamia użytkowników SMS-em - wszystko z odpowiednią obsługą błędów i logiką ponownych prób.
Po ukończeniu tej lekcji opanujesz:
Zbuduj gotową do produkcji integrację, która:
Zacznij z trybem Ask, aby zrozumieć co istnieje:
@src/integrations"Przeanalizuj istniejący kod integracji:- Które API są częściowo zaimplementowane?- Jaka jest obecna architektura?- Jaka obsługa błędów istnieje?- Czego brakuje do użytku produkcyjnego?- Luki bezpieczeństwa?"
"Pomóż mi zrozumieć te API:- Stripe: Przepływ przetwarzania płatności- SendGrid: Najlepsze praktyki API e-mail- Twilio: Gwarancje dostarczenia SMSStwórz porównanie limitów, metod autoryzacji i kodów błędów"
Przełącz na tryb Agent:
"Zaprojektuj architekturę zunifikowanego systemu powiadomień:- Abstrakcyjny interfejs dla wszystkich powiadomień- Implementacje specyficzne dla dostawców- Strategie ponownych prób i fallback- Zarządzanie konfiguracją- Wzorce obsługi błędówStwórz diagram architektury i interfejsy"
Wiele API ma już dostępne serwery MCP:
# GitHub MCP - Pełny dostęp do GitHub APIclaude mcp add --transport sse github https://api.githubcopilot.com/mcp/
# Linear MCP - Śledzenie zadańclaude mcp add --transport sse linear https://mcp.linear.app/sse
# Jira MCP - Integracja Atlassian# Uwaga: Oficjalny endpoint Atlassian to https://mcp.atlassian.com/v1/sse (Beta)# Do konfiguracji lokalnej użyj pakietów społeczności:claude mcp add jira -- npx -y @mcp-devtools/jira
# Slack MCP - Integracja wiadomościclaude mcp add slack -- npx -y @modelcontextprotocol/server-slack
Z zainstalowanym GitHub MCP:
"Używając GitHub MCP, pokaż mi:- Jak tworzyć zadania programowo- Konfigurację webhook dla zdarzeń PR- Obsługę limitów żądań- Przykłady zapytań GraphQL"
// MCP zapewnia bezpośredni dostęp do API:"Utwórz zadanie GitHub w repozytorium 'myorg/myrepo' z:- Tytułem: 'Integracja płatności nie działa'- Etykietami: ['bug', 'high-priority']- Przypisanym: '@username'"
// Bezpośrednie użycie narzędzi przez MCP"Używając Linear MCP:- Utwórz zadanie w projekcie 'Integracja API'- Ustaw priorytet na pilny- Dodaj do obecnego sprintu"
// MCP obsługuje:// - Autoryzację// - Limity żądań// - Ponowne próby błędów// - Parsowanie odpowiedzi
// Potrzebna ręczna implementacjaconst linear = new LinearClient({ apiKey: process.env.LINEAR_API_KEY});
// Musisz zaimplementować:// - Obsługę błędów// - Logikę ponownych prób// - Limity żądań// - Definicje typów
"Koordynuj pomiędzy wieloma serwerami MCP:1. Gdy płatność Stripe się powiedzie (używając naszej integracji)2. Utwórz zadanie Linear do realizacji (Linear MCP)3. Wyślij na kanał #sales w Slack (Slack MCP)4. Zaktualizuj rekord klienta w bazie danych"
// AI może używać wielu MCP sekwencyjnie
"Używając Context7 MCP, pobierz najnowszą dokumentację dla:- Stripe Node.js SDK- SendGrid API v3- Webhook Twilio
Porównaj z naszą obecną implementacją"
Używaj serwerów MCP gdy:
Buduj własne gdy:
"Utwórz bazową klasę integracji z:- Logiką ponownych prób z exponential backoff- Wzorcem circuit breaker- Logowaniem żądań/odpowiedzi- Standaryzacją błędów- Zbieraniem metryk- Obsługą limitów żądań"
Przykład klasy bazowej:
export abstract class BaseIntegration { protected abstract readonly name: string; protected abstract readonly baseURL: string; protected abstract readonly maxRetries: number;
private circuitBreaker: CircuitBreaker; private metrics: MetricsCollector;
constructor(protected config: IntegrationConfig) { this.circuitBreaker = new CircuitBreaker({ timeout: config.timeout || 30000, errorThreshold: config.errorThreshold || 50, resetTimeout: config.resetTimeout || 60000 });
this.metrics = new MetricsCollector(this.name); }
protected async makeRequest<T>( method: string, endpoint: string, data?: any, options: RequestOptions = {} ): Promise<T> { const url = `${this.baseURL}${endpoint}`;
return this.circuitBreaker.execute(async () => { const startTime = Date.now();
try { const response = await this.executeWithRetry( method, url, data, options );
this.metrics.recordSuccess(Date.now() - startTime); return response; } catch (error) { this.metrics.recordError(error); throw this.standardizeError(error); } }); }
private async executeWithRetry<T>( method: string, url: string, data?: any, options: RequestOptions = {} ): Promise<T> { let lastError: Error;
for (let attempt = 0; attempt <= this.maxRetries; attempt++) { try { if (attempt > 0) { await this.delay(this.calculateBackoff(attempt)); }
return await this.executeRequest<T>(method, url, data, options); } catch (error) { lastError = error;
if (!this.isRetryable(error) || attempt === this.maxRetries) { throw error; }
logger.warn(`Próba ponowienia ${attempt + 1} dla ${url}`, { error }); } }
throw lastError!; }
private calculateBackoff(attempt: number): number { const baseDelay = 1000; const maxDelay = 32000; const delay = Math.min(baseDelay * Math.pow(2, attempt), maxDelay); return delay + Math.random() * 1000; // Dodaj jitter }
protected abstract isRetryable(error: any): boolean; protected abstract standardizeError(error: any): IntegrationError;}
@integrations/base.ts"Utwórz implementacje dostawców dla:1. StripeIntegration rozszerzającą BaseIntegration2. SendGridIntegration rozszerzającą BaseIntegration3. TwilioIntegration rozszerzającą BaseIntegrationUwzględnij odpowiednią autoryzację, obsługę błędów i funkcje specyficzne dla API"
"Utwórz NotificationService który:- Orkiestruje wszystkie trzy serwisy- Obsługuje przepływ płatność → e-mail → SMS- Implementuje strategie fallback- Zapewnia zachowanie transakcyjne- Wspiera operacje zbiorowe"
"Utwórz bezpieczne zarządzanie konfiguracją:- Ładowanie konfiguracji opartej na środowisku- Zaszyfrowane przechowywanie kluczy API- Obsługa rotacji kluczy- Walidacja konfiguracji- Aktualizacje konfiguracji w czasie wykonania"
Przykład konfiguracji:
export class IntegrationConfig { private static instance: IntegrationConfig; private configs: Map<string, ProviderConfig> = new Map();
private constructor() { this.loadConfigurations(); this.validateConfigurations(); this.setupKeyRotation(); }
static getInstance(): IntegrationConfig { if (!IntegrationConfig.instance) { IntegrationConfig.instance = new IntegrationConfig(); } return IntegrationConfig.instance; }
getConfig(provider: string): ProviderConfig { const config = this.configs.get(provider); if (!config) { throw new Error(`Konfiguracja nie znaleziona dla dostawcy: ${provider}`); }
// Odszyfruj klucze API na żądanie return { ...config, apiKey: this.decryptKey(config.encryptedApiKey) }; }
private loadConfigurations() { // Ładowanie z zmiennych środowiskowych lub bezpiecznego magazynu this.configs.set('stripe', { encryptedApiKey: process.env.STRIPE_API_KEY_ENCRYPTED!, webhookSecret: process.env.STRIPE_WEBHOOK_SECRET, apiVersion: '2023-10-16', timeout: 30000, maxRetries: 3 });
// Podobnie dla SendGrid i Twilio }
private decryptKey(encryptedKey: string): string { // Implementacja bezpiecznego odszyfrowywania return decrypt(encryptedKey, process.env.MASTER_KEY!); }}
"Implementuj bezpieczeństwo żądań:- Walidacja podpisu webhook- Podpisywanie żądań dla API które tego wymagają- Rotacja kluczy API bez przestojów- Logika odświeżania tokenów OAuth- Parsowanie nagłówków limitów żądań"
"Utwórz middleware dla:- Sanityzacji danych wejściowych- Filtrowania danych wyjściowych (usuń wrażliwe dane)- Śledzenia ID żądań- Logowania audytowego- Wykrywania zagrożeń"
"Utwórz system obsługi błędów:- Kategoryzuj błędy (limit żądań, autoryzacja, sieć, itp.)- Implementuj odpowiednie strategie ponownych prób na typ- Utwórz mechanizmy fallback- Kolejka martwych liter dla nieudanych żądań- Procedury odzyskiwania błędów"
Przykład obsługi błędów:
export class IntegrationError extends Error { constructor( message: string, public code: string, public provider: string, public isRetryable: boolean, public originalError?: any, public context?: Record<string, any> ) { super(message); this.name = 'IntegrationError'; }
static fromStripeError(error: any): IntegrationError { const retryableCodes = ['rate_limit', 'api_connection_error'];
return new IntegrationError( error.message || 'Błąd Stripe API', error.code || 'unknown_error', 'stripe', retryableCodes.includes(error.code), error, { type: error.type, param: error.param, requestId: error.requestId } ); }
static fromSendGridError(error: any): IntegrationError { const isRetryable = error.code >= 500 || error.code === 429;
return new IntegrationError( error.message || 'SendGrid API błąd', `sendgrid_${error.code}`, 'sendgrid', isRetryable, error, { response: error.response?.body } ); }}
"Implementuj wzorzec circuit breaker:- Śledź wskaźniki awarii per serwis- Otwórz obwód przy przekroczeniu progu- Stan półotwarty do testowania odzyskiwania- Konfigurowalne progi- Metryki i alertowanie"
"Implementuj mechanizmy fallback:- Drugorzędny dostawca e-mail jeśli SendGrid nie działa- Kolejka SMS dla awarii Twilio- Odpowiedzi cache dla operacji odczytu- Strategie graceful degradation- Preferencje powiadomień użytkowników"
@integrations"Wygeneruj testy dla:- Testy jednostkowe z mock API- Testy integracji z sandbox API- Testowanie scenariuszy błędów- Symulacja limitów żądań- Zachowanie circuit breaker- Obsługa webhook"
Przykład struktury testów:
describe('StripeIntegration', () => { let stripe: StripeIntegration; let mockServer: MockServer;
beforeAll(async () => { mockServer = await createMockStripeServer(); stripe = new StripeIntegration({ apiKey: 'test_key', baseURL: mockServer.url }); });
describe('Przetwarzanie płatności', () => { it('powinno obsłużyć udaną płatność', async () => { mockServer.onPost('/charges').reply(200, { id: 'ch_test123', status: 'succeeded' });
const result = await stripe.createCharge({ amount: 1000, currency: 'usd' });
expect(result.status).toBe('succeeded'); });
it('powinno ponowić próbę przy błędach sieciowych', async () => { let attempts = 0; mockServer.onPost('/charges').reply(() => { attempts++; if (attempts < 3) { throw new NetworkError('Connection reset'); } return [200, { status: 'succeeded' }]; });
const result = await stripe.createCharge({ amount: 1000, currency: 'usd' });
expect(attempts).toBe(3); expect(result.status).toBe('succeeded'); }); });});
"Utwórz system monitorowania:- Śledzenie czasu odpowiedzi API- Wskaźniki sukcesu/porażki per endpoint- Monitorowanie użycia limitów żądań- Alertowanie wskaźnika błędów- Śledzenie kosztów per serwis"
"Utwórz narzędzia debugowania:- Narzędzie replay żądań/odpowiedzi- Wizualizacja timeline wywołań API- Analiza wzorców błędów- Profilowanie wydajności- Generatory danych testowych"
Pozwól AI efektywnie analizować dokumentację API:
// Metoda 1: Używanie serwerów MCP (jeśli dostępne)"Używając GitHub MCP, pokaż mi:- Endpointy API repozytorium- Wzorce autoryzacji- Szczegóły limitów żądań- Konfigurację webhook"
// Metoda 2: Używanie Context7 MCP dla dokumentacji"Używając Context7 MCP, pobierz najnowsze:- Referencję Stripe API- Najlepsze praktyki dla idempotentności- Wytyczne bezpieczeństwa webhook"
// Metoda 3: Ręczna analiza dokumentacji@stripe-api-docs.md"Wyciągnij kluczowe informacje:- Metoda autoryzacji- Limity żądań- Kody błędów i znaczenia- Obsługa idempotentności- Zdarzenia webhookStwórz przewodnik referencyjny"
Zapewnij kompatybilność API:
"Wygeneruj testy kontraktów z dokumentacji API:- Schematy żądań/odpowiedzi- Pola wymagane vs opcjonalne- Definicje typów- Reguły walidacji- Wykrywanie breaking change"
Implementuj smart retry:
// Różne strategie dla różnych błędówconst retryStrategies = { rate_limit: { shouldRetry: true, backoffMultiplier: 1, maxRetries: 10, respectRetryAfter: true }, network_error: { shouldRetry: true, backoffMultiplier: 2, maxRetries: 3, addJitter: true }, invalid_request: { shouldRetry: false }};
Problem: Uderzanie w limity API podczas operacji zbiorowych
Rozwiązanie:
// Implementuj algorytm token bucketclass RateLimiter { async executeWithRateLimit<T>( operation: () => Promise<T> ): Promise<T> { await this.acquireToken(); return operation(); }}
Problem: Endpointy webhook narażone na ataki replay
Rozwiązanie:
// Walidacja podpisów i znaczników czasufunction validateWebhook(payload, signature, timestamp) { if (Date.now() - timestamp > 300000) { // 5 minut throw new Error('Znacznik czasu webhook zbyt stary'); } // Weryfikuj podpis}
Problem: Częściowe awarie w operacjach wieloserwisowych
Rozwiązanie:
// Implementuj wzorzec saga dla transakcji rozproszonychclass NotificationSaga { async execute(transaction: NotificationTransaction) { const steps = this.planSteps(transaction); const completed = [];
try { for (const step of steps) { await step.execute(); completed.push(step); } } catch (error) { // Kompensuj w odwrotnej kolejności for (const step of completed.reverse()) { await step.compensate(); } throw error; } }}
Ulepsz swój system integracji:
Redundancja wielu dostawców
Zaawansowane funkcje
Optymalizacja wydajności
Orkiestracja serwerów MCP
Twoja integracja jest gotowa do produkcji gdy:
Zespoły używające tych wzorców raportują:
Przed wdrożeniem:
Opanowałeś wzorce integracji API. Gotowy na więcej?
Buduj API Gateway
Stwórz zunifikowaną bramę API dla wszystkich integracji
Dodaj warstwę GraphQL
Zbuduj warstwę GraphQL nad REST API
Utwórz SDK
Zapakuj swoje integracje jako SDK wielokrotnego użytku
Kontynuuj do Projektowanie bazy danych →