Skip to content

Composable API Documentation ​

Overview ​

Composable APIs are external API composables located in app/composables/api/. These composables make HTTP requests to external backend APIs (not Nuxt server routes) and provide a clean, reusable interface for API operations.

Key Characteristics ​

  • External APIs: Make requests to external backend APIs (via API_BASE_URL)
  • Composable Pattern: Vue 3 composables for reusable API logic
  • Type-Safe: Full TypeScript support with type definitions
  • Error Handling: Built-in error handling and logging
  • Authentication: Automatic token injection via API client

API Structure ​

app/composables/api/
├── useAccountApi.ts          # Account status checking
├── useAppDataApi.ts          # Dashboard and app data
├── useAppDataQueries.ts      # TanStack Query: app/dashboard data
├── useAssetsApi.ts          # Asset operations
├── useAssetsQueries.ts       # TanStack Query: assets
├── useAuthApi.ts             # Authentication operations
├── useCollectionApi.ts      # Collection/collage operations
├── useCollectionQueries.ts   # TanStack Query: collections/collages
├── useCommonApis.ts         # Common API operations
├── useDownloadApi.ts         # Download operations
├── useExternalShareApi.ts    # External sharing operations
├── useFetchClient.ts         # Fetch client implementation
├── useFolderApi.ts           # Folder operations
├── useFolderQueries.ts       # TanStack Query: folders
├── useMutationClient.ts      # TanStack Query: mutation helpers
├── useNotificationApi.ts    # Notification operations
├── useProfileApi.ts          # User profile operations
├── useProfileQueries.ts      # TanStack Query: profile
├── useQueryClient.ts         # TanStack Query client access
├── queryKeys.ts              # TanStack Query key factory
├── useSearchApi.ts           # Search operations
├── useShareDialogApi.ts      # Share dialog operations
├── useSharingApi.ts          # Sharing operations
├── useSharingQueries.ts      # TanStack Query: sharing
├── useSupportApi.ts          # Support/feedback operations
└── useWorkspaceApi.ts        # Workspace operations

Note: The project uses TanStack Vue Query for server state. Use use*Queries composables and useQueryClient/useMutationClient for cached, deduplicated requests; use use*Api for one-off or imperative calls.

API Categories ​

Authentication APIs ​

  • useAuthApi - Login, logout, password reset, token login

Account & Workspace APIs ​

Data APIs ​

Asset & Content APIs ​

Search & Discovery APIs ​

Sharing APIs ​

User & Profile APIs ​

Utility APIs ​

TanStack Query (Server State & Caching) ​

  • TanStack Query - Overview of queryKeys, useQueryClient, useMutationClient, and useQueries composables (useAppDataQueries, useAssetsQueries, useCollectionQueries, useFolderQueries, useProfileQueries, useSharingQueries). Use for cached, reactive data; use useApi for one-off or imperative calls.

How Composable APIs Work ​

Request Flow ​

  1. Composable Call: Component calls composable function
  2. API Client: Composable uses $api from Nuxt app
  3. Request Interceptor: API client adds auth token, headers
  4. External API: Request sent to external backend API
  5. Response Interceptor: Response processed, errors handled
  6. Return Data: Composable returns typed response

Authentication ​

Composable APIs automatically include authentication:

typescript
// API client automatically adds token from HTTP-only cookie
const { $api } = useNuxtApp()

// Token is added automatically (via server-side cookie)
await $api('/digital/get-tiles', {
  method: 'GET',
  query: { workspace_id: workspaceId }
})

Error Handling ​

All composables include error handling:

typescript
try {
  const response = await $api('/endpoint')
  return response
} catch (error: any) {
  console.error('[API] Error:', error)
  throw error  // Re-throw for component handling
}

Usage Examples ​

Basic Usage ​

typescript
// In component
const { getTiles } = useAppDataApi()

const loadTiles = async () => {
  try {
    const tiles = await getTiles(workspaceId)
    // Use tiles...
  } catch (error) {
    // Handle error...
  }
}

With Loading States ​

typescript
const loading = ref(false)
const { getDashboardData } = useAppDataApi()

const loadDashboard = async () => {
  loading.value = true
  try {
    const data = await getDashboardData(workspaceId, instanceId)
    // Use data...
  } catch (error) {
    // Handle error...
  } finally {
    loading.value = false
  }
}

Multiple Composables ​

typescript
const { getTiles } = useAppDataApi()
const { getBanners } = useAppDataApi()
const { getFolders } = useAppDataApi()

const loadAll = async () => {
  const [tiles, banners, folders] = await Promise.all([
    getTiles(workspaceId),
    getBanners(workspaceId, instanceId),
    getFolders(workspaceId, false)
  ])
  // Use data...
}

API Client Integration ​

Composable APIs use the global $api client from app/plugins/api-client.ts:

  • Automatic Auth: Token from HTTP-only cookie
  • Error Handling: 401 auto-logout, account status monitoring
  • Request/Response Interceptors: Custom logic for all requests
  • Base URL: Routes to API_BASE_URL environment variable

Type Safety ​

All composables use TypeScript types:

typescript
import type { Tile, Banner, DashboardData } from '~/types'

const { getTiles } = useAppDataApi()

// TypeScript knows return type
const tiles: Tile[] = await getTiles(workspaceId)

Best Practices ​

  1. Error Handling: Always wrap API calls in try-catch
  2. Loading States: Use loading refs for async operations
  3. Type Safety: Import and use types from ~/types
  4. Composable Reuse: Use composables in multiple components
  5. Error Logging: Errors are logged automatically, handle in UI