---
name: api_client
kind: function
lang: ts
domain: core
version: "1.0.0"
purity: impure
signature: "apiClient(config: APIClientConfig): { get<T>(path, params?): Promise<T>; post<T>(path, body?): Promise<T>; put<T>(path, body?): Promise<T>; patch<T>(path, body?): Promise<T>; del<T>(path): Promise<T> }"
description: "Factory HTTP que retorna un cliente con get/post/put/patch/del. Usa fetch nativo con base_url+headers, parsea JSON automaticamente, llama on_error/on_unauthorized segun status code. Zero dependencias externas."
tags: [http, fetch, client, rest, api, factory, core]
uses_functions: []
uses_types: [APIClientConfig_ts_core]
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
params:
  - name: config
    desc: "Configuracion: base_url (URL base sin slash final), headers opcionales, callbacks on_error y on_unauthorized"
output: "Objeto con metodos get/post/put/patch/del que hacen fetch con la config aplicada"
tested: false
tests: []
test_file_path: ""
file_path: "frontend/functions/core/api_client.ts"
---

## Ejemplo

```typescript
import { apiClient } from './api_client'

const api = apiClient({
  base_url: 'http://localhost:8484/api',
  headers: { 'X-Client': 'dashboard' },
  on_unauthorized: () => (window.location.href = '/login'),
})

const users = await api.get<User[]>('/users')
const user = await api.post<User>('/users', { name: 'Lucas', email: 'lucas@example.com' })
await api.del('/users/123')
```

## Con parametros de query

```typescript
const results = await api.get<User[]>('/users', { search: 'lucas', role: 'admin' })
// GET /users?search=lucas&role=admin
```

## Notas

- `del` es un alias de DELETE para evitar colision con la keyword `delete` de JS
- Si la respuesta no es `application/json`, retorna el texto crudo como `T`
- `on_unauthorized` se llama ANTES de `on_error` en status 401
- Los errores de red (sin conexion, CORS) tambien llaman a `on_error`
- Creado una vez a nivel de modulo/app, pasado a hooks via `fetch_fn`
