Documentación Humalight BFF

Guía completa para usar tu Backend for Frontend

Compatible con Strapi 5, APIs REST custom y más

Backend for Frontend (BFF) para Strapi 5

Este proyecto Next.js actúa como un Backend for Frontend (BFF) que se sitúa entre tus aplicaciones cliente y tu instancia de Strapi 5. Proporciona una capa de abstracción que oculta los detalles de implementación de Strapi y permite un mejor control sobre las peticiones.

🏗️ Arquitectura

Cliente (Web/Mobile) 
    ↓
Backend for Frontend (Next.js)
    ↓
Strapi 5 CMS

🚀 Configuración

1. Variables de Entorno

Crea o edita el archivo .env.local en la raíz del proyecto:

STRAPI_API_URL=http://localhost:1337
STRAPI_API_TOKEN=tu_token_de_strapi

2. Instalación

npm install

3. Desarrollo

npm run dev

El servidor estará disponible en http://localhost:3000.

📡 API Endpoints

Health Check

Verifica el estado de la conexión con Strapi:

GET /api/health

Respuesta exitosa:

{
  "status": "healthy",
  "strapi": "connected",
  "timestamp": "2025-11-22T10:00:00.000Z"
}

Proxy de Strapi

Todos los endpoints de Strapi están disponibles a través del proxy:

GET    /api/strapi/{endpoint}
POST   /api/strapi/{endpoint}
PUT    /api/strapi/{endpoint}
DELETE /api/strapi/{endpoint}

Ejemplos:

Obtener artículos:

GET /api/strapi/articles

Obtener un artículo específico:

GET /api/strapi/articles/1

Con query parameters (populate, filters, etc.):

GET /api/strapi/articles?populate=*&filters[slug][$eq]=mi-articulo

Crear un artículo:

POST /api/strapi/articles
Content-Type: application/json

{
  "data": {
    "title": "Nuevo Artículo",
    "content": "Contenido del artículo"
  }
}

Actualizar un artículo:

PUT /api/strapi/articles/1
Content-Type: application/json

{
  "data": {
    "title": "Título actualizado"
  }
}

Eliminar un artículo:

DELETE /api/strapi/articles/1

💻 Uso en el Cliente

Desde tu aplicación web:

// Llamar al BFF en lugar de Strapi directamente
const response = await fetch('http://localhost:3000/api/strapi/articles?populate=*');
const data = await response.json();

Desde React/Next.js:

// En un componente de Next.js
async function getArticles() {
  const res = await fetch('/api/strapi/articles?populate=*', {
    cache: 'no-store' // o usa next: { revalidate: 60 }
  });
  
  if (!res.ok) {
    throw new Error('Failed to fetch articles');
  }
  
  return res.json();
}

export default async function ArticlesPage() {
  const { data } = await getArticles();
  
  return (
    <div>
      {data.map((article) => (
        <div key={article.id}>
          <h2>{article.title}</h2>
          <p>{article.description}</p>
        </div>
      ))}
    </div>
  );
}

🔧 Cliente de Strapi (Uso Directo)

También puedes usar el cliente de Strapi directamente en tus Server Components o API Routes:

import { strapiClient } from '@/lib/strapi';

// En un Server Component o API Route
async function getData() {
  try {
    const response = await strapiClient.get('/api/articles?populate=*');
    return response.data;
  } catch (error) {
    console.error('Error fetching data:', error);
    throw error;
  }
}

Métodos disponibles:

// GET
await strapiClient.get('/api/articles');

// POST
await strapiClient.post('/api/articles', {
  data: { title: 'Nuevo artículo' }
});

// PUT
await strapiClient.put('/api/articles/1', {
  data: { title: 'Título actualizado' }
});

// DELETE
await strapiClient.delete('/api/articles/1');

📁 Estructura del Proyecto

backend-for-frontend/
├── app/
│   ├── api/
│   │   ├── health/
│   │   │   └── route.ts          # Health check endpoint
│   │   └── strapi/
│   │       └── [...path]/
│   │           └── route.ts      # Proxy dinámico para Strapi
│   ├── layout.tsx
│   └── page.tsx
├── lib/
│   ├── config/
│   │   └── strapi.config.ts      # Configuración de Strapi
│   ├── strapi/
│   │   ├── client.ts             # Cliente HTTP para Strapi
│   │   ├── types.ts              # Tipos de Strapi
│   │   └── index.ts              # Exports públicos
│   └── types/
│       ├── strapi-models.ts      # Tipos de tus modelos
│       └── index.ts
├── .env.local                     # Variables de entorno
├── package.json
└── README.md

🛡️ Ventajas del BFF

  1. SeguridadEl token de Strapi nunca se expone al cliente
  • FlexibilidadPuedes transformar los datos antes de enviarlos al cliente
  • CachéControl fino sobre el caching de datos
  • ValidaciónValidar datos antes de enviarlos a Strapi
  • AgregaciónCombinar múltiples llamadas a Strapi en una sola
  • VersionadoMantener diferentes versiones de la API
  • MonitoringCentralizar logs y métricas
  • 🔐 Seguridad

    📝 Personalización

    Agregar nuevos endpoints personalizados

    Crea un nuevo archivo en app/api/:

    // app/api/custom/route.ts
    import { NextResponse } from 'next/server';
    import { strapiClient } from '@/lib/strapi';
    
    export async function GET() {
      // Lógica personalizada
      const articles = await strapiClient.get('/api/articles');
      const authors = await strapiClient.get('/api/authors');
      
      // Combinar o transformar datos
      return NextResponse.json({
        articles: articles.data,
        authors: authors.data,
      });
    }
    

    Definir tipos personalizados

    Edita lib/types/strapi-models.ts para agregar tus propios modelos de Strapi:

    export interface MiModelo {
      id: number;
      documentId: string;
      campo1: string;
      campo2: number;
      createdAt: string;
      updatedAt: string;
    }
    

    🧪 Testing

    # Verificar que el servidor funciona
    curl http://localhost:3000/api/health
    
    # Probar el proxy
    curl http://localhost:3000/api/strapi/articles
    

    📚 Recursos

    🤝 Contribuir

    Este es tu proyecto, personalízalo según tus necesidades.