API Communication

How the frontend communicates with the backend API

API Communication

Overview

The frontend communicates with the backend exclusively through REST API calls. All requests go through the useApi composable, which handles authentication headers and token refresh automatically.

The useApi Composable

const api = useApi()

// GET request (authenticated)
const profile = await api('/api/v1/user/profile')

// POST request
const result = await api('/api/v1/auth/login', {
  method: 'POST',
  body: { email, password }
})

What It Does

  1. Base URL injection — Prepends NUXT_PUBLIC_API_BASE_URL to all requests
  2. Auth headers — Automatically adds Authorization: Bearer <token> when a token exists
  3. 401 retry — On a 401 response, attempts to refresh the token and retry the request once
  4. Logout on failure — If the refresh fails, clears the auth store (logs the user out)

Request Flow

Frontend Request
    │
    ├── Add Authorization header (if token exists)
    │
    ▼
Backend API
    │
    ├── 200/201 → Return data
    │
    ├── 401 → Refresh token
    │           │
    │           ├── Success → Retry original request
    │           │
    │           └── Failure → Logout user
    │
    └── Other error → Return error to caller

API Endpoints Used

Frontend FeatureBackend EndpointMethod
Register/api/v1/auth/registerPOST
Login/api/v1/auth/loginPOST
Social Login/api/v1/auth/socialPOST
Logout/api/v1/auth/logoutPOST
Token Refresh/api/v1/auth/token/refreshPOST
Forgot Password/api/v1/auth/forgot-passwordPOST
Reset Password/api/v1/auth/reset-passwordPOST
User Profile/api/v1/user/profileGET
Change Password/api/v1/user/change-passwordPOST
Pricing Plans/api/v1/plansGET
Checkout Session/api/v1/subscription/checkoutPOST
Subscription Status/api/v1/subscriptionGET

CORS Configuration

The backend must allow requests from the frontend origin. Set CORS_ALLOW_ORIGIN in the backend's .env.local:

# Local development
CORS_ALLOW_ORIGIN=^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$

# Production
CORS_ALLOW_ORIGIN=^https://yourdomain\.com$

Error Handling

Each composable handles API errors with a consistent pattern:

const { error, isLoading } = useAuth()

// error is a Ref<string | null>
// isLoading is a Ref<boolean>

Errors from the backend are parsed from the response JSON ({ "error": "message" }) and exposed as reactive refs that components can display.