Skip to content

Multi-Instance Configuration ​

Learn how to configure and use multiple @pubflow/flowfull-client instances in your application.

TIP

Multi-instance support allows you to connect to multiple backends simultaneously, perfect for microservices architecture or separating concerns (e.g., main API vs analytics API).

Why Multi-Instance? ​

Multi-instance support allows you to:

  • Connect to multiple backends simultaneously
  • Separate concerns (e.g., main API vs analytics API)
  • Use different authentication for different services
  • Implement microservices architecture
  • Connect to different environments (staging, production)

Configuration ​

Basic Setup ​

Create multiple client instances:

typescript
// src/api/clients.ts
import { createFlowfull } from '@pubflow/flowfull-client';

// Main API client
export const mainApi = createFlowfull('https://api.example.com', {
  headers: {
    'X-Client-Type': 'main'
  }
});

// Analytics API client
export const analyticsApi = createFlowfull('https://analytics.example.com', {
  headers: {
    'X-Client-Type': 'analytics'
  }
});

// Payments API client
export const paymentsApi = createFlowfull('https://payments.example.com', {
  headers: {
    'X-Client-Type': 'payments'
  }
});

Using Multiple Instances ​

In React Components ​

typescript
// src/pages/Dashboard.tsx
import { useState, useEffect } from 'react';
import { mainApi, analyticsApi } from '../api/clients';

interface User {
  id: string;
  name: string;
  email: string;
}

interface AnalyticsEvent {
  id: string;
  event_type: string;
  timestamp: string;
}

function Dashboard() {
  const [users, setUsers] = useState<User[]>([]);
  const [events, setEvents] = useState<AnalyticsEvent[]>([]);

  useEffect(() => {
    fetchData();
  }, []);

  async function fetchData() {
    // Fetch from main API
    const usersResponse = await mainApi.query('/users').limit(10).get<User[]>();
    if (usersResponse.success) {
      setUsers(usersResponse.data || []);
    }

    // Fetch from analytics API
    const eventsResponse = await analyticsApi.query('/events').limit(20).get<AnalyticsEvent[]>();
    if (eventsResponse.success) {
      setEvents(eventsResponse.data || []);
    }
  }

  return (
    <div>
      <h2>Users</h2>
      <ul>
        {users.map(user => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>

      <h2>Recent Events</h2>
      <ul>
        {events.map(event => (
          <li key={event.id}>{event.event_type}</li>
        ))}
      </ul>
    </div>
  );

Separate Authentication ​

Each instance can have its own session:

typescript
// src/pages/MultiAuthExample.tsx
import { useState, useEffect } from 'react';
import { mainApi, analyticsApi } from '../api/clients';

function MultiAuthExample() {
  const [mainUser, setMainUser] = useState(null);
  const [analyticsUser, setAnalyticsUser] = useState(null);

  async function handleMainLogin() {
    const response = await mainApi.post('/auth/login',
      { email: 'user@example.com', password: 'pass' },
      { includeSession: false }
    );

    if (response.success) {
      mainApi.setSessionId(response.data.session_id);
      const profileResponse = await mainApi.get('/profile');
      setMainUser(profileResponse.data);
    }
  }

  async function handleAnalyticsLogin() {
    const response = await analyticsApi.post('/auth/login',
      { email: 'analyst@example.com', password: 'pass' },
      { includeSession: false }
    );

    if (response.success) {
      analyticsApi.setSessionId(response.data.session_id);
      const profileResponse = await analyticsApi.get('/profile');
      setAnalyticsUser(profileResponse.data);
    }
  }

  return (
    <div>
      <div>
        <h2>Main API</h2>
        {mainUser ? (
          <p>Logged in as {mainUser.name}</p>
        ) : (
          <button onClick={handleMainLogin}>Login to Main</button>
        )}
      </div>

      <div>
        <h2>Analytics API</h2>
        {analyticsUser ? (
          <p>Logged in as {analyticsUser.name}</p>
        ) : (
          <button onClick={handleAnalyticsLogin}>Login to Analytics</button>
        )}
      </div>
    </div>
  );
}

Environment Variables ​

Use environment variables for different environments:

bash
# .env.local
VITE_MAIN_API_URL=https://api.example.com
VITE_ANALYTICS_API_URL=https://analytics.example.com
VITE_PAYMENTS_API_URL=https://payments.example.com
typescript
// src/api/clients.ts
import { createFlowfull } from '@pubflow/flowfull-client';

export const mainApi = createFlowfull(import.meta.env.VITE_MAIN_API_URL);
export const analyticsApi = createFlowfull(import.meta.env.VITE_ANALYTICS_API_URL);
export const paymentsApi = createFlowfull(import.meta.env.VITE_PAYMENTS_API_URL);

Real-World Example ​

DadosBall game with separate game server and auth server:

typescript
// src/api/clients.ts
import { createFlowfull } from '@pubflow/flowfull-client';

// Auth server (Flowless)
export const authApi = createFlowfull(process.env.EXPO_PUBLIC_AUTH_URL!);

// Game server (custom Flowfull backend)
export const gameApi = createFlowfull(process.env.EXPO_PUBLIC_GAME_URL!);

// src/screens/GameLobby.tsx
import { useState, useEffect } from 'react';
import { authApi, gameApi } from '../api/clients';

function GameLobby() {
  const [user, setUser] = useState(null);
  const [games, setGames] = useState([]);

  useEffect(() => {
    fetchData();
  }, []);

  async function fetchData() {
    // Get user from auth server
    const userResponse = await authApi.get('/profile');
    if (userResponse.success) {
      setUser(userResponse.data);
    }

    // Get games from game server
    const gamesResponse = await gameApi.query('/games').limit(10).get();
    if (gamesResponse.success) {
      setGames(gamesResponse.data || []);
    }
  }

  return (
    <div>
      <h1>Welcome, {user?.name}!</h1>
      <h2>Available Games</h2>
      <ul>
        {games.map(game => (
          <li key={game.id}>{game.name}</li>
        ))}
      </ul>
    </div>
  );
}

Next Steps ​