Examples

Learn hyperwiz through real-world examples. From basic setup to advanced patterns, discover how to build secure, scalable applications.

Real Examples

Production-ready code samples

Best Practices

Interceptor and retry patterns

Step by Step

Clear, detailed explanations

Code Examples

Production-ready implementations and patterns

Basic HTTP Methods

Getting Started

Get started with simple HTTP requests using hyperwiz.

TypeScript

import { createClient } from 'hyperwiz';

// Create a simple client
const api = createClient('https://api.example.com');

// GET request
const users = await api.get('/users');

// POST request
const newUser = await api.post('/users', { 
  name: 'John Doe', 
  email: 'john@example.com' 
});

// PUT request
const updatedUser = await api.put('/users/1', { 
  name: 'John Updated' 
});

// PATCH request
const patchedUser = await api.patch('/users/1', { 
  email: 'john.new@example.com' 
});

// DELETE request
const deleted = await api.delete('/users/1');

// Handle responses
if (users.success) {
  console.log('Users:', users.data);
} else {
  console.error('Error:', users.error);
}

JavaScript

import { createClient } from 'hyperwiz';

// Create a simple client
const api = createClient('https://api.example.com');

// GET request
const users = await api.get('/users');

// POST request
const newUser = await api.post('/users', { 
  name: 'John Doe', 
  email: 'john@example.com' 
});

// PUT request
const updatedUser = await api.put('/users/1', { 
  name: 'John Updated' 
});

// PATCH request
const patchedUser = await api.patch('/users/1', { 
  email: 'john.new@example.com' 
});

// DELETE request
const deleted = await api.delete('/users/1');

// Handle responses
if (users.success) {
  console.log('Users:', users.data);
} else {
  console.error('Error:', users.error);
}

Smart Caching with IndexedDB

Performance

Use persistent caching with IndexedDB for better performance and offline support.

TypeScript

import { createClient } from 'hyperwiz';

// Create client with IndexedDB caching
const api = createClient('https://api.example.com', {
  cache: {
    enabled: true,
    maxAge: 10 * 60 * 1000,  // Cache for 10 minutes
    maxSize: 100,             // Maximum 100 cached items
    storage: 'indexeddb',     // Use IndexedDB for persistence
    includeQueryParams: true, // Include query params in cache key
    cacheableMethods: ['GET', 'HEAD'], // Cache GET and HEAD requests
    cacheableStatusCodes: [200, 304]   // Cache 200 and 304 responses
  },
  logging: true
});

// First request: fetches from server
const users1 = await api.get('/users'); // ⏳ Network request

// Second request: served from cache (instant)
const users2 = await api.get('/users'); // 💾 Cache hit (instant)

// Request with query params: cached separately
const filteredUsers = await api.get('/users?status=active'); // ⏳ Network request
const filteredUsers2 = await api.get('/users?status=active'); // 💾 Cache hit

// Cache automatically expires after maxAge
// Cache automatically evicts old entries when maxSize is reached

// Cache management
class CacheManager {
  static async clearCache() {
    const cacheStorage = new IndexedDBCacheStorage();
    await cacheStorage.clear();
    console.log('Cache cleared');
  }

  static async getCacheStats() {
    const cacheStorage = new IndexedDBCacheStorage();
    const keys = await cacheStorage.keys();
    console.log(`Cache contains ${keys.length} items`);
    return keys;
  }
}

JavaScript

import { createClient } from 'hyperwiz';

// Create client with IndexedDB caching
const api = createClient('https://api.example.com', {
  cache: {
    enabled: true,
    maxAge: 10 * 60 * 1000,  // Cache for 10 minutes
    maxSize: 100,             // Maximum 100 cached items
    storage: 'indexeddb',     // Use IndexedDB for persistence
    includeQueryParams: true, // Include query params in cache key
    cacheableMethods: ['GET', 'HEAD'], // Cache GET and HEAD requests
    cacheableStatusCodes: [200, 304]   // Cache 200 and 304 responses
  },
  logging: true
});

// First request: fetches from server
const users1 = await api.get('/users'); // ⏳ Network request

// Second request: served from cache (instant)
const users2 = await api.get('/users'); // 💾 Cache hit (instant)

// Request with query params: cached separately
const filteredUsers = await api.get('/users?status=active'); // ⏳ Network request
const filteredUsers2 = await api.get('/users?status=active'); // 💾 Cache hit

// Cache automatically expires after maxAge
// Cache automatically evicts old entries when maxSize is reached

// Cache management
class CacheManager {
  static async clearCache() {
    const cacheStorage = new IndexedDBCacheStorage();
    await cacheStorage.clear();
    console.log('Cache cleared');
  }

  static async getCacheStats() {
    const cacheStorage = new IndexedDBCacheStorage();
    const keys = await cacheStorage.keys();
    console.log(`Cache contains ${keys.length} items`);
    return keys;
  }
}

Auto Retry with Configuration

Reliability

Configure automatic retry with adaptive backoff for reliable requests.

TypeScript

import { createClient } from 'hyperwiz';

// Create client with retry configuration
const api = createClient('https://api.example.com', {
  retry: {
    maxRetries: 3,           // Retry up to 3 times
    retryDelay: 1000,        // Start with 1 second delay
    maxDelay: 10000,         // Maximum 10 second delay
    backoffMultiplier: 2,    // Double the delay each retry
    retryOnStatus: [408, 429, 500, 502, 503, 504], // Retry on these status codes
    retryOnNetworkError: true // Retry on network errors
  },
  logging: true              // Enable request/response logging
});

// All requests automatically retry if they fail
// Retries preserve the original HTTP method, headers, and body
const data = await api.get('/unreliable-endpoint');
const user = await api.post('/users', { name: 'John' }); // POST retries as POST

// You can also use simple boolean for default retry settings
const simpleApi = createClient('https://api.example.com', {
  retry: true, // Uses default: 3 retries, 1s delay, exponential backoff
  logging: true
});

JavaScript

import { createClient } from 'hyperwiz';

// Create client with retry configuration
const api = createClient('https://api.example.com', {
  retry: {
    maxRetries: 3,           // Retry up to 3 times
    retryDelay: 1000,        // Start with 1 second delay
    maxDelay: 10000,         // Maximum 10 second delay
    backoffMultiplier: 2,    // Double the delay each retry
    retryOnStatus: [408, 429, 500, 502, 503, 504], // Retry on these status codes
    retryOnNetworkError: true // Retry on network errors
  },
  logging: true              // Enable request/response logging
});

// All requests automatically retry if they fail
const data = await api.get('/unreliable-endpoint');
const user = await api.post('/users', { name: 'John' });

// Simple boolean for default retry settings
const simpleApi = createClient('https://api.example.com', {
  retry: true, // Uses default settings
  logging: true
});

Bearer Token Authentication

Authentication

Add authentication tokens to requests using interceptors.

TypeScript

import { createClient } from 'hyperwiz';

const api = createClient('https://api.example.com');

// Add token interceptor - automatically adds token to all requests
api.addBefore((config, url) => {
  const token = localStorage.getItem('token');
  if (token) {
    return {
      ...config,
      headers: {
        ...config.headers,
        'Authorization': `Bearer ${token}`
      }
    };
  }
  return config;
});

// Login (no token yet - works correctly)
const login = await api.post('/login', { 
  username: 'admin', 
  password: '123' 
});

// Store token after successful login
if (login.success) {
  localStorage.setItem('token', login.data.token);
}

// Now all requests automatically include the token
const profile = await api.get('/user/profile'); // ✅ Token added automatically
const posts = await api.post('/posts', { title: 'New Post' }); // ✅ Token added automatically

// Manual token for specific requests
const manualAuth = await api.get('/admin/data', {
  'Authorization': 'Bearer admin-token'
});

JavaScript

import { createClient } from 'hyperwiz';

const api = createClient('https://api.example.com');

// Add token interceptor
api.addBefore((config, url) => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers = {
      ...config.headers,
      'Authorization': `Bearer ${token}`
    };
  }
  return config;
});

// Login
const login = await api.post('/login', { 
  username: 'admin', 
  password: '123' 
});

// Store token
if (login.success) {
  localStorage.setItem('token', login.data.token);
}

// All requests now include token
const profile = await api.get('/user/profile');
const posts = await api.post('/posts', { title: 'New Post' });

// Manual token
const manualAuth = await api.get('/admin/data', {
  'Authorization': 'Bearer admin-token'
});

Cookie-Based Authentication

Authentication

Use session-based authentication with cookies for server-side sessions.

TypeScript

import { createClient } from 'hyperwiz';

// For session-based authentication with cookies
const api = createClient('http://localhost:4000', {
  credentials: 'include', // Important for cookies
  logging: true
});

// Login - server sets session cookie
const login = await api.post('/login', { 
  username: 'admin', 
  password: '123' 
});

// Subsequent requests - cookies are automatically sent
const profile = await api.get('/user/profile');
const data = await api.get('/protected-data');

// Cross-origin requests with cookies
const crossOriginApi = createClient('https://api.example.com', {
  credentials: 'include', // Important for cookies
  logging: true
});

// Cookies are automatically sent, developer adds any other headers
const profile = await api.get('/user/profile', {
  'X-API-Key': 'your-api-key'
});

JavaScript

import { createClient } from 'hyperwiz';

// For session-based authentication
const api = createClient('http://localhost:4000', {
  credentials: 'include', // Important for cookies
  logging: true
});

// Login - server sets session cookie
const login = await api.post('/login', { 
  username: 'admin', 
  password: '123' 
});

// All subsequent requests include cookies
const profile = await api.get('/user/profile');
const data = await api.get('/protected-data');

// Cross-origin with cookies
const crossOriginApi = createClient('https://api.example.com', {
  credentials: 'include',
  logging: true
});

const profile = await api.get('/user/profile', {
  'X-API-Key': 'your-api-key'
});

Custom Interceptors

Advanced

Add request, response, and error interceptors for complete control.

TypeScript

import { createClient } from 'hyperwiz';

const api = createClient('https://api.example.com');

// Request interceptor - runs before each request
api.addBefore((config, url) => {
  console.log(`🚀 Making ${config.method} request to ${url}`);
  
  // Add custom headers
  config.headers = {
    ...config.headers,
    'X-Request-ID': generateRequestId(),
    'X-Client-Version': '1.0.0'
  };
  
  return config;
});

// Response interceptor - runs after successful responses
api.addAfter((response, data, url) => {
  console.log(`✅ Response from ${url}:`, data);
  
  // Transform response data
  if (data && typeof data === 'object' && 'items' in data) {
    return {
      ...data,
      totalCount: data.items.length
    };
  }
  
  return data;
});

// Error interceptor - runs when errors occur
api.addErrorHandler((error, url, requestConfig) => {
  console.error(`❌ Error for ${requestConfig?.method} ${url}:`, error);
  
  // Log to external service
  logErrorToService(error, url, requestConfig);
  
  // Transform error
  if (error.status === 401) {
    return {
      ...error,
      message: 'Authentication required. Please log in again.'
    };
  }
  
  return error;
});

// Helper functions
function generateRequestId(): string {
  return Math.random().toString(36).substring(2, 15);
}

function logErrorToService(error: any, url: string, config: any) {
  // Implementation for error logging service
  console.log('Logging error to service:', { error, url, config });
}

JavaScript

import { createClient } from 'hyperwiz';

const api = createClient('https://api.example.com');

// Request interceptor
api.addBefore((config, url) => {
  console.log(`🚀 Making ${config.method} request to ${url}`);
  
  // Add custom headers
  config.headers = {
    ...config.headers,
    'X-Request-ID': generateRequestId(),
    'X-Client-Version': '1.0.0'
  };
  
  return config;
});

// Response interceptor
api.addAfter((response, data, url) => {
  console.log(`✅ Response from ${url}:`, data);
  
  // Transform response data
  if (data && typeof data === 'object' && 'items' in data) {
    return {
      ...data,
      totalCount: data.items.length
    };
  }
  
  return data;
});

// Error interceptor
api.addErrorHandler((error, url, requestConfig) => {
  console.error(`❌ Error for ${requestConfig?.method} ${url}:`, error);
  
  // Log to external service
  logErrorToService(error, url, requestConfig);
  
  // Transform error
  if (error.status === 401) {
    return {
      ...error,
      message: 'Authentication required. Please log in again.'
    };
  }
  
  return error;
});

// Helper functions
function generateRequestId() {
  return Math.random().toString(36).substring(2, 15);
}

function logErrorToService(error, url, config) {
  console.log('Logging error to service:', { error, url, config });
}

React Hook Pattern

React

Use hyperwiz in React applications with custom hooks for better organization.

TypeScript

import { useState, useCallback } from 'react';
import { createClient } from 'hyperwiz';

function useApi() {
  const [api] = useState(() => createClient('https://api.example.com', {
    retry: true,
    cache: true,
    logging: process.env.NODE_ENV === 'development'
  }));

  const login = useCallback(async (credentials: any) => {
    const response = await api.post('/auth/login', credentials);
    if (response.success) {
      localStorage.setItem('auth-token', response.data.token);
    }
    return response;
  }, [api]);

  const logout = useCallback(() => {
    localStorage.removeItem('auth-token');
  }, []);

  const getProfile = useCallback(async () => {
    const token = localStorage.getItem('auth-token');
    return await api.get('/user/profile', {
      'Authorization': `Bearer ${token}`
    });
  }, [api]);

  const createPost = useCallback(async (postData: any) => {
    const token = localStorage.getItem('auth-token');
    return await api.post('/posts', postData, {
      'Authorization': `Bearer ${token}`
    });
  }, [api]);

  return { api, login, logout, getProfile, createPost };
}

// Usage in component
function ProfileComponent() {
  const { getProfile, createPost } = useApi();
  const [profile, setProfile] = useState(null);
  const [loading, setLoading] = useState(false);
  
  const handleLoadProfile = async () => {
    setLoading(true);
    const response = await getProfile();
    if (response.success) {
      setProfile(response.data);
    }
    setLoading(false);
  };
  
  const handleCreatePost = async (postData: any) => {
    const response = await createPost(postData);
    if (response.success) {
      console.log('Post created:', response.data);
    }
  };
  
  return (
    <div>
      <button onClick={handleLoadProfile} disabled={loading}>
        {loading ? 'Loading...' : 'Load Profile'}
      </button>
      {profile && (
        <div>
          <h2>{profile.name}</h2>
          <p>{profile.email}</p>
        </div>
      )}
    </div>
  );
}

JavaScript

import { useState, useCallback } from 'react';
import { createClient } from 'hyperwiz';

function useApi() {
  const [api] = useState(() => createClient('https://api.example.com', {
    retry: true,
    cache: true,
    logging: process.env.NODE_ENV === 'development'
  }));

  const login = useCallback(async (credentials) => {
    const response = await api.post('/auth/login', credentials);
    if (response.success) {
      localStorage.setItem('auth-token', response.data.token);
    }
    return response;
  }, [api]);

  const logout = useCallback(() => {
    localStorage.removeItem('auth-token');
  }, []);

  const getProfile = useCallback(async () => {
    const token = localStorage.getItem('auth-token');
    return await api.get('/user/profile', {
      'Authorization': `Bearer ${token}`
    });
  }, [api]);

  const createPost = useCallback(async (postData) => {
    const token = localStorage.getItem('auth-token');
    return await api.post('/posts', postData, {
      'Authorization': `Bearer ${token}`
    });
  }, [api]);

  return { api, login, logout, getProfile, createPost };
}

// Usage in component
function ProfileComponent() {
  const { getProfile, createPost } = useApi();
  const [profile, setProfile] = useState(null);
  const [loading, setLoading] = useState(false);
  
  const handleLoadProfile = async () => {
    setLoading(true);
    const response = await getProfile();
    if (response.success) {
      setProfile(response.data);
    }
    setLoading(false);
  };
  
  const handleCreatePost = async (postData) => {
    const response = await createPost(postData);
    if (response.success) {
      console.log('Post created:', response.data);
    }
  };
  
  return (
    <div>
      <button onClick={handleLoadProfile} disabled={loading}>
        {loading ? 'Loading...' : 'Load Profile'}
      </button>
      {profile && (
        <div>
          <h2>{profile.name}</h2>
          <p>{profile.email}</p>
        </div>
      )}
    </div>
  );
}