> ## Documentation Index
> Fetch the complete documentation index at: https://docs.base44.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Módulo Functions

> Invoca funciones de backend personalizadas mediante base44.functions.

<Warning>
  Esta página es parte de una habilidad de agente de codificación con IA y está escrita para agentes, no para humanos. Para la documentación de Base44 legible por humanos, consulta la [documentación para desarrolladores](/developers).
</Warning>

# Módulo Functions

Invoca funciones de backend personalizadas mediante `base44.functions`.

## Contenido

* [Método](#method)
* [Invocar funciones](#invoking-functions) (Frontend, subida de archivos, rol de servicio, REST API)
* [Escribir funciones de backend](#writing-backend-functions) (Básica, rol de servicio, secretos, errores)
* [Requisitos de configuración](#setup-requirements)
* [Modos de autenticación](#authentication-modes)

## Métodos

### `invoke`

```javascript theme={null}
base44.functions.invoke(functionName, data?): Promise<AxiosResponse>
```

* `functionName`: Nombre de la función de backend
* `data`: Objeto opcional de parámetros (enviado como JSON, o multipart si contiene objetos File)
* **Devuelve la respuesta axios SIN PROCESAR** — el JSON que devolvió tu función vive en **`.data`**, no en el objeto de nivel superior. El valor resuelto es `{ data, status, headers, … }`.
* **Lanza en una respuesta no-2xx.** El cuerpo del error está en `err.response.data`.

```javascript theme={null}
try {
  // ⚠️ invoke() devuelve la respuesta axios SIN PROCESAR, por lo que el JSON que devolvió tu función
  //    vive en `.data` — NO en el objeto de nivel superior.
  const res = await base44.functions.invoke("process-order", { orderId });
  const result = res.data;        // ✅  por ejemplo, res.data.success
  // const result = res;          // ❌  esto es { data, status, headers, … }
} catch (err) {
  // invoke() LANZA en una respuesta no-2xx; el cuerpo del error está en err.response.data.
  console.error(err.response?.data);
}
```

### `fetch`

```javascript theme={null}
base44.functions.fetch(path, init?): Promise<Response>
```

Método de bajo nivel que realiza una solicitud HTTP directa a una ruta de función de backend y devuelve el objeto `Response` nativo. Úsalo cuando necesites respuestas en streaming, métodos HTTP personalizados o acceso a la respuesta sin procesar.

* `path`: Ruta de la función (por ejemplo, `/streaming_demo` o `/my-function/endpoint`)
* `init`: Opciones de fetch nativas opcionales (`RequestInit`)
* Devuelve: Objeto `Response` nativo

## Invocar funciones

### Desde el frontend

```javascript theme={null}
const res = await base44.functions.invoke("processOrder", {
  orderId: "order-123",
  action: "ship"
});

// invoke() resuelve a la respuesta axios sin procesar — lee el JSON de tu función en .data
const result = res.data;
console.log(result);
```

### Respuesta en streaming (usando fetch)

```javascript theme={null}
// Usa fetch() para respuestas en streaming (SSE, texto por trozos, etc.)
const response = await base44.functions.fetch("/stream-data", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ prompt: "Tell me a story" })
});

// Leer como un stream
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  console.log(decoder.decode(value));
}
```

### Métodos HTTP personalizados (usando fetch)

```javascript theme={null}
// PUT, PATCH, DELETE u otros métodos
const response = await base44.functions.fetch("/my-resource/123", {
  method: "DELETE"
});
console.log(response.status); // 204
```

### Con subida de archivo

```javascript theme={null}
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];

// Usa automáticamente multipart/form-data cuando hay objetos File presentes
const res = await base44.functions.invoke("uploadDocument", {
  file: file,
  category: "invoices"
});
const result = res.data; // el JSON de la función está en .data
```

### Con rol de servicio (backend)

```javascript theme={null}
// Dentro de otra función de backend
const res = await base44.asServiceRole.functions.invoke("adminTask", {
  userId: "user-123"
});
const result = res.data; // el JSON de la función está en .data
```

### Mediante REST API (curl)

Las funciones se pueden llamar mediante HTTP POST a tu dominio de app:

```bash theme={null}
curl -X POST "https://<app-domain>/functions/<function-name>" \
  -H "Content-Type: application/json" \
  -d '{"key": "value"}'
```

## Escribir funciones de backend

Las funciones de backend se ejecutan en Deno. Deben exportar usando `Deno.serve()`.

### Estructura del directorio de funciones

Una función de backend es una carpeta bajo `base44/functions/` con un archivo `entry.ts` o `entry.js`:

```
base44/
  functions/
    process-order/
      entry.ts
```

El nombre de la función es la ruta desde `base44/functions/` a la carpeta que contiene `entry.ts`. Por ejemplo, `base44/functions/process-order/entry.ts` se despliega como `process-order`, y `base44/functions/orders/process/entry.ts` se despliega como `orders/process`.

Para instrucciones completas de configuración y despliegue, consulta [functions-create.md](https://docs.base44.com/developers/skills/base44-sdk/references/../../base44-cli/references/functions-create.md) en base44-cli.

### Estructura básica

```javascript theme={null}
// base44/functions/process-order/entry.ts
import { createClientFromRequest } from "npm:@base44/sdk";

Deno.serve(async (req) => {
  // Obtén el cliente autenticado desde la solicitud
  const base44 = createClientFromRequest(req);
  
  // Analiza la entrada
  const { orderId, action } = await req.json();
  
  // Tu lógica aquí
  const order = await base44.entities.Orders.get(orderId);
  
  // Devuelve la respuesta
  return Response.json({
    success: true,
    order: order
  });
});
```

### Con acceso de rol de servicio

```javascript theme={null}
import { createClientFromRequest } from "npm:@base44/sdk";

Deno.serve(async (req) => {
  const base44 = createClientFromRequest(req);
  
  // Comprueba que el usuario está autenticado
  const user = await base44.auth.me();
  if (!user) {
    return Response.json({ error: "Unauthorized" }, { status: 401 });
  }
  
  // Usa el rol de servicio para operaciones de administrador
  const allOrders = await base44.asServiceRole.entities.Orders.list();
  
  return Response.json({ orders: allOrders });
});
```

### Usar secretos

```javascript theme={null}
Deno.serve(async (req) => {
  // Accede a las variables de entorno (configuradas en la configuración de la app)
  const apiKey = Deno.env.get("STRIPE_API_KEY");
  
  const response = await fetch("https://api.stripe.com/v1/charges", {
    headers: {
      "Authorization": `Bearer ${apiKey}`
    }
  });
  
  return Response.json(await response.json());
});
```

### Manejo de errores

```javascript theme={null}
import { createClientFromRequest } from "npm:@base44/sdk";

Deno.serve(async (req) => {
  try {
    const base44 = createClientFromRequest(req);
    const { orderId } = await req.json();
    
    const order = await base44.entities.Orders.get(orderId);
    if (!order) {
      return Response.json(
        { error: "Order not found" },
        { status: 404 }
      );
    }
    
    return Response.json({ order });
    
  } catch (error) {
    return Response.json(
      { error: error.message },
      { status: 500 }
    );
  }
});
```

## Requisitos de configuración

1. Habilita las funciones de backend en la configuración de la app (requiere plan apropiado)
2. Crea archivos de función en `base44/functions/`
3. Configura secretos mediante el panel de la app para claves API

## Modos de autenticación

| Modo            | Contexto                                  | Permisos                                          |
| --------------- | ----------------------------------------- | ------------------------------------------------- |
| Usuario         | `base44.functions.invoke()`               | Se ejecuta con los permisos del usuario que llama |
| Rol de servicio | `base44.asServiceRole.functions.invoke()` | Acceso de nivel administrador                     |

Dentro de la función, usa `createClientFromRequest(req)` para obtener un cliente que herede el contexto de autenticación del llamante.

## Definiciones de tipos

**Cómo obtener nombres de función tipados:** La CLI de Base44 puede generar una augmentación de `FunctionNameRegistry` desde tu proyecto. Para saber cómo ejecutarlo, usa la habilidad **base44-cli**.

```typescript theme={null}
/**
 * Registro de nombres de función.
 * Aumenta esta interfaz para habilitar autocompletado para nombres de función.
 * Normalmente lo rellena el generador de tipos de la CLI de Base44.
 */
interface FunctionNameRegistry {}

/**
 * Tipo de nombre de función - usa claves del registro si está aumentado, de lo contrario string.
 */
type FunctionName = keyof FunctionNameRegistry extends never ? string : keyof FunctionNameRegistry;

/**
 * Opciones para functions.fetch(). Usa opciones de fetch nativas directamente.
 */
type FunctionsFetchInit = RequestInit;

/** Módulo Functions para invocar funciones de backend personalizadas. */
interface FunctionsModule {
  /**
   * Invoca una función de backend personalizada por nombre.
   *
   * Si algún parámetro es un objeto File, la solicitud se enviará automáticamente
   * como multipart/form-data. De lo contrario, se enviará como JSON.
   *
   * @param functionName - El nombre de la función a invocar.
   * @param data - Objeto opcional que contiene parámetros nombrados para la función.
   * @returns Promesa que resuelve a la respuesta de la función.
   */
  invoke(functionName: FunctionName, data?: Record<string, any>): Promise<any>;

  /**
   * Realiza una solicitud HTTP directa a una ruta de función de backend y devuelve el Response nativo.
   *
   * Usar para respuestas en streaming (SSE, texto por trozos), métodos HTTP personalizados,
   * o cuando necesites acceso sin procesar a la respuesta.
   *
   * @param path - Ruta de función, por ejemplo `/streaming_demo` o `/my-function/endpoint`
   * @param init - Opciones de fetch nativas opcionales.
   * @returns Promesa que resuelve a un Response de fetch nativo.
   */
  fetch(path: string, init?: FunctionsFetchInit): Promise<Response>;
}
```

<Note>Esta página fue traducida usando IA. Para obtener la información más precisa y actualizada, consulta la [versión en inglés](/).</Note>
