<Meta title='@dxtmisha/en/functional/Composables/useApiRef - API Requests'/>

# `useApiRef`

A composable for working with API requests in Vue components. Returns reactive data, state flags, and load management methods.

## Key Features
- **Lazy Initialization**: Requests and dependency watchers are only initialized upon the first access to data (`data` or `item`). This allows declaring `useApiRef` without immediate network or CPU overhead.
- **Global Scope (Eternal)**: If the `unmounted` parameter is set to `false`, reactivity is moved to `EffectScopeGlobal`. This ensures requests continue to update even after the component that created them is unmounted.

**Parameters:**
- `path?: RefOrNormal<string | undefined>` — endpoint path (can be a reactive `Ref`).
- `options?: ApiOptions` — request options (`ApiFetch` object or method name string).
- `reactivity?: boolean` — automatically re-run the request when `path`, `options`, or locale change. Default: `true`.
- `conditions?: RefType<boolean>` — reactive execution condition. If `false` — the request is not made and data is cleared.
- `transformation?: (data: T, isResponseContractValid?: ApiDataValidation) => ApiData<R>` — response transformation function applied before saving to `data`. Receives the contract validation result as the second argument.
- `validateResponseContract?: (data: T) => ApiDataValidation` — function to validate the response data contract.
- `unmounted?: boolean` — if `true` (default), data is cleared and the watcher is stopped when the component unmounts. When `false`, `EffectScopeGlobal` is used for background persistence.
- `apiInstance?: ApiInstance` — API instance to use for the request. Defaults to `Api.getItem()`.

**Returns (`UseApiRef<R>`):**

Reactive states:
- `data: ComputedRef<ApiData<R> | undefined>` — A reference to the loaded data (Computed). Initiates **lazy initialization** (request and watcher) on the first access.
- `item: Ref<ApiData<R> | undefined>` — Direct reference to data (Ref). Also initiates lazy initialization upon access.
- `isResponseContractValid: ComputedRef<boolean>` — `true` if the response contract is valid (`success` status).
- `responseValidationResult: ComputedRef<ApiDataValidation | undefined>` — the full contract validation result object.
- `starting: ComputedRef<boolean>` — Returns `true` if data has never been requested yet or is in the process of fetching the first portion of data (`data` is still `undefined`).
- `loading: Ref<boolean>` — Returns `true` if any network request (initial or subsequent `reset`) is currently in progress.
- `reading: Ref<boolean>` — A flag for an active data reading/processing process.

Methods:
- `isStarting(): boolean` — A synchronous method that returns the current value of the `starting` flag.
- `isLoading(): boolean` — A synchronous method that returns the current value of the `loading` flag.
- `isReading(): boolean` — A synchronous method that returns the current value of the `reading` flag.
- `getItem(): ApiData<R> | undefined` — Method to get the current value of `data` without creating a reactive dependency.
- `init(awaitFetch?: boolean): Promise<void>` — Method for explicit request and watcher initialization. Triggered automatically on first access to `data`. If `awaitFetch` is `true`, it waits for the first request to complete.
- `reset(): Promise<void>` — An asynchronous method to force re-run the request. Cancels the current active request (if any) and initiates a new one.
- `stop(): void` — Stops watching reactive dependencies and resets `data` to `undefined`.
- `abort(): void` — Cancels the current HTTP request via the internal `AbortController`, while keeping already loaded data in `data`.

## Lazy Initialization

Requests and watching mechanisms **are not started** immediately when `useApiRef` is called. They are activated only when accessing `data`, `item`, or calling `init()`. This optimizes the performance of setup scripts.

## Global Conditions

`setApiRefGlobalConditions(conditions)` — sets a global condition for all `useApiRef` instances. Only works on the first call.

## SSR and Initialization

The `init` method is designed to manage the primary data loading process, which is critical for the correct operation of **Server Side Rendering (SSR)** and ensuring fast interface rendering on the client.

### Mechanism of Operation (Hydration)

1.  **Server Side (SSR):**
    When the page is first opened, `await init()` should be called in `async setup()`. This forces the server to wait for the API response and render the component with ready-made data. The received data is automatically placed in the state cache, which is then passed to the client.

2.  **Client Side (Hydration):**
    When the browser "hydrates" the page, `useApiRef` first checks for data in the cache. If data is there (received from the server), it is immediately applied to `data`, avoiding a duplicate API request.

3.  **Dynamic Navigation (Client-side Nav):**
    If the user navigates to the page dynamically (without a page reload), the component renders immediately without waiting for `init()` to complete. This allows for instantly showing a **skeleton** or loading indicator (`loading`) while data is being fetched in the background.
## ApiOptions Object

`ApiOptions` — can accept a string with the `method` name (e.g., `'GET'`) or an object of type `ApiFetch`. Fields of the `ApiFetch` object:

- `path?: string` — path to the endpoint script relative to the base URL (e.g., `'users/list'`).
- `pathFull?: string` — full URL of the request. If specified, ignores `api` and `path`.
- `api?: boolean` — whether to add the base URL before `path`. Default: `true`.
- `method?: ApiMethod` — HTTP method (`'GET'`, `'POST'`, `'PUT'`, `'DELETE'`). Default: `'GET'`.
- `request?: FormData | Record<string, any> | string` — request body (for POST/PUT) or query parameters (for GET). Passed as JSON or `FormData`.
- `headers?: Record<string, string> | null` — additional request headers. `null` — disable all headers.
- `type?: string` — `Content-Type` value. Default: `'application/json;charset=UTF-8'`.
- `auth?: boolean` — whether to add authentication headers.
- `toData?: boolean` — if `true`, automatically unwraps `data` from the `{ data: ... }` wrapper. Default: `true`.
- `hideError?: boolean` — suppresses error output to `console.error` on failure. Default: `false`.
- `globalPreparation?: boolean` — whether to run the global `setPreparation` hook before this request. Default: `true`.
- `globalEnd?: boolean` — whether to run the global `setEnd` hook after the response. Default: `true`.
- `queryReturn?: (query: Response) => Promise<any>` — response handler instead of standard JSON reading.
- `init?: RequestInit` — additional options for native `fetch()` (CORS, cache mode, etc.).
- `controller?: AbortController` — controller for canceling the request.
- `retry?: number` — number of retries on failure.

## Example

```typescript
import { ref } from 'vue'
import { useApiRef, setApiRefGlobalConditions } from '@dxtmisha/functional'

const userId = ref('123')
const isAuthenticated = ref(true)

// Global condition (all requests only run if authenticated)
setApiRefGlobalConditions(isAuthenticated)

const {
  data: user,
  starting,
  loading,
  reading,
  getItem,
  reset,
  stop,
  abort
} = useApiRef(
  () => `users/${userId.value}`,
  { method: 'GET' },
  true // Reactively re-run on userId change
)

// Check state without reactivity
console.log(getItem()) // undefined before first access to data

// Force reload
await reset()

// Cancel request (without clearing data)
abort()

// Stop watching (clears data)
stop()
```
