Construyendo un Frontend Antes de que la API esté lista: Sin accesorios Brittle (Español (Spanish))

Construyendo un Frontend Antes de que la API esté lista: Sin accesorios Brittle

Saturday, 13 December 2025

//

16 minute read

Introducción

¿Cuántas veces has estado bloqueado esperando que las API de backend estén listas? ¿O has pasado horas manteniendo datos simulados que se vuelven rancios en el momento en que cambian los requisitos?

Entrar mostlylucid.mockllmapi - una plataforma de burla ASP.NET Core lista para la producción que utiliza modelos de lenguaje grande para generar respuestas API realistas y contextualmente conscientes sobre la marcha. En lugar de mantener los accesorios JSON, usted obtiene burlas inteligentes que se adaptan a sus peticiones y recordar estado a través de llamadas.

Lo que apoya: Cada protocolo que necesita: REST, GraphQL, gRPC, SignalR, Server-Sent Events y OpenAPI. A diferencia de los dispositivos estáticos, las respuestas se generan dinámicamente en función del contexto de solicitud, haciendo que los flujos de trabajo de varios pasos y los escenarios de pruebas complejos sean triviales.

Enlaces al proyecto

NuGet NuGet Liberación de GitHub Licencia: Unlicense

Tres maneras de usarlo

Usted puede utilizar principalmentelucid.mockllmapi de tres maneras, dependiendo de lo aislado que desee que su entorno dev sea:

  1. Paquete ASP.NET Core NuGet - Añadir a sus proyectos existentes
  2. Herramienta CLI independiente - Executable entre plataformas (descargar desde liberaciones)
  3. Contenedor Docker - Cero instalación requerida

La característica del asesino: Memoria de contexto

Guía completa: Documentación de contextos API

Las API simuladas tradicionales tienen un defecto fatal: cada solicitud es independiente. Consigue un usuario con ID 42, luego consigue sus pedidos, y recibirás pedidos para ID 99. Sin consistencia.

Contextos de la API resolver esto con memoria compartida a través de peticiones relacionadas:

// Request 1: Get a user
// Note: 'context' is a simple query parameter - no cookies or sessions needed
fetch('/api/users/123?context=checkout-session')
// Response: { id: 42, name: "Alice Smith", email: "[email protected]" }

// Request 2: Get orders (same context parameter)
fetch('/api/orders?userId=42&context=checkout-session')
// Response: { userId: 42, customerName: "Alice Smith", items: [...] }
// Perfect! Same user, consistent data

El LLM ve solicitudes anteriores en el mismo contexto y genera datos consistentes. Este es el cambiador de juego para flujos de trabajo de varios pasos.

Características:

Ciclo de vida:

  • Expiración automática después de 15 minutos de inactividad (configurable)
  • Cada solicitud actualiza el temporizador

Comportamiento:

  • Extracción inteligente de TODOS los campos de las respuestas

Seguridad:

  • Cero fugas de memoria - los contextos se limpian

Casos de uso:

  • Perfecto para CI/CD - no hay estado entre carreras

Inicio rápido

Opción 1: Paquete NuGet

dotnet add package mostlylucid.mockllmapi
// Program.cs
builder.Services.AddLLMockApi(builder.Configuration);
app.MapLLMockApi("/api/mock");

Opción 2: Herramienta CLI

# Download from https://github.com/scottgal/LLMApi/releases
llmock serve --port 5000

Opción 3: Docker

Guía completa: Guía de implementación de Docker

git clone https://github.com/scottgal/LLMApi.git
cd LLMApi
docker compose up -d

Requisitos previos: motor LLM

Necesitas uno de los: Ollama, OpenAI, o LM Studio:

# Recommended: Ollama with ministral-3:3b (ultra-fast, accurate JSON generation)
ollama pull ministral-3:3b

Ver Guía de modelos de Ollama para todas las recomendaciones y comparaciones del modelo.

Inténtalo inmediatamente

Una vez en ejecución, haga su primera petición:

curl http://localhost:5000/api/mock/users
# Response: [{"id": 1, "name": "Alice Johnson", "email": "[email protected]"}, ...]

¡Eso es todo! Ahora tienes una API simulada que genera datos realistas bajo demanda.

Ejemplo real: Buscar en su mayoríalucid.net

Aquí está el código de búsqueda real de este blog - este es el código de salida de producción sin cambios, no se necesitan adaptaciones para el simulacro:

// typeahead.js from mostlylucid.net
export function typeahead() {
    return {
        query: '',
        results: [],
        search() {
            fetch(`/api/search/${encodeURIComponent(this.query)}`)
                .then(response => response.json())
                .then(data => { this.results = data; });
        }
    }
}

Muérdelo:

# Using CLI
llmock serve --port 5000

# Query returns contextual results
curl http://localhost:5000/api/search/markdown
# LLM generates blog posts about Markdown

curl http://localhost:5000/api/search/docker
# LLM generates blog posts about Docker

Cada respuesta es única y realista, adaptándose a la consulta.

Control de forma: Definir su esquema

Más allá de sólo generar datos aleatorios, a menudo necesita un control preciso sobre la estructura JSON. El control de forma le permite decirle al LLM exactamente qué estructura generar - la característica más poderosa para el desarrollo de frontend.

Forma básica

# Without shape - random structure
curl http://localhost:5000/api/mock/users
# Response: { "userId": 1, "fullName": "Alice" }

# With shape - you control it
curl "http://localhost:5000/api/mock/users" \
  -H 'X-Response-Shape: {"id":0,"name":"string","email":"string"}'
# Response: { "id": 1, "name": "Alice", "email": "[email protected]" }

Tres formas de especificar la forma:

  1. Parámetro de consulta - ?shape={...}
  2. Encabezado HTTP - X-Response-Shape: {...} (recomendado)
  3. Órgano de solicitud - {"shape": {...}}

Forma anidada

const shape = {
  company: {
    id: 0,
    name: "string",
    employees: [{
      id: 0,
      firstName: "string",
      department: { id: 0, name: "string" },
      projects: [{ id: 0, title: "string" }]
    }]
  }
};

fetch('/api/mock/company', {
  headers: { 'X-Response-Shape': JSON.stringify(shape) }
});

Alineación de TypeScript

interface User {
  id: number;
  name: string;
  email: string;
}

const USER_SHAPE: Partial<User> = { id: 0, name: "", email: "" };

// Shape becomes your type definition AND mock schema!

Flujos de trabajo de varios pasos con contexto

Ahora combinemos el control de forma con contextos API para manejar flujos de trabajo complejos y de varios pasos. ¿Recuerda la característica de memoria de contexto de antes? Así es como brilla en operaciones asíncronas del mundo real.

Este ejemplo del servicio de traducción de mayoritariamentelucid.net muestra cómo el LLM mantiene el estado a través de un flujo de trabajo completo asíncrono:

# Step 1: Start translation
curl -X POST http://localhost:5000/api/translate/start?context=translate-session \
  -d '{"language": "es", "markdown": "# Hello World"}'
# Response: { "taskId": "abc-123", "status": "processing" }

# Step 2: Check status (LLM remembers the task)
curl http://localhost:5000/api/translate/status/abc-123?context=translate-session
# Response: { "taskId": "abc-123", "status": "complete" }

# Step 3: Get result (same taskId!)
curl http://localhost:5000/api/translate/result/abc-123?context=translate-session
# Response: { "taskId": "abc-123", "translatedText": "# Hola Mundo" }

Note cómo taskId es consistente en todas las solicitudes. El contexto lo hace posible.

Más allá del REST: Todos los Protocolos

Hasta ahora nos hemos centrado en el REST, pero las aplicaciones modernas necesitan más. Ya sea que esté construyendo con GraphQL, implementando funciones en tiempo real con SignalR, o trabajando con los servicios de gRPC, en su mayoría lucid.mockllmapi lo tiene cubierto.

Protocolos compatibles:

  • ✓ REST
  • ✓ GraphQL
  • ✓ gRPC
  • ✓ SeñalR
  • ✓ Eventos de envío de servidores (SSE)
  • ✓ OpenAPI / Swagger

GráficaQL

Guía: Sección GráficaQL

curl -X POST http://localhost:5000/api/mock/graphql \
  -d '{"query": "{ users { id name email } }"}'

La consulta ES la forma - no se necesita un esquema separado.

gRPC

Guía completa: Soporte gRPC

# Upload .proto file
curl -X POST http://localhost:5116/api/grpc-protos \
  --data-binary "@user_service.proto"

# Call via JSON or binary Protobuf
curl -X POST http://localhost:5116/api/grpc/userservice/UserService/GetUser \
  -d '{"user_id": 123}'

SeñalR en tiempo real

Guía: Guía de demostración de SignalR

const connection = new signalR.HubConnectionBuilder()
    .withUrl("/hub/mock")
    .build();

connection.on("DataUpdate", (message) => {
    console.log(message.data); // Live generated data
});

await connection.start();
await connection.invoke("SubscribeToContext", "stock-prices");

Perfecto para el prototipado del salpicadero.

Eventos de envío de servidores (SSE)

Guía: Modos de transmisión SSE

const eventSource = new EventSource('/api/mock/stream/users');
eventSource.onmessage = (event) => {
    const data = JSON.parse(event.data);
    console.log('Token:', data.chunk); // Progressive generation
};

OpenAPI / Swagger

Guía completa: Características de OpenAPI

# CLI: Load any OpenAPI spec
llmock serve --spec https://petstore3.swagger.io/api/v3/openapi.json

# All endpoints become live mocks automatically
curl http://localhost:5000/petstore/pet/123

Herramientas enchufables: Mix Real & Mock Data

Guía completa: Herramientas y acciones

A veces necesita un enfoque híbrido - datos reales de la producción combinada con datos simulados generados. El sistema de herramientas pluggable le permite llamar APIs reales durante la generación de simulacros, creando escenarios de prueba increíblemente realistas.

{
  "Tools": [{
    "Name": "getUserData",
    "Type": "http",
    "HttpConfig": {
      "Endpoint": "https://api.production.com/users/{userId}",
      "Headers": { "Authorization": "Bearer ${PROD_API_KEY}" }
    }
  }]
}
curl "http://localhost:5000/api/mock/orders?useTool=getUserData&userId=123"

La maqueta obtiene datos de usuario REAL, luego el LLM genera órdenes usándolos. Extremadamente útil para pruebas realistas con flujos de trabajo híbridos simulados/reales.

Integración básica de ASP.NET

Si está construyendo con ASP.NET Core, la integración es perfecta. La belleza de este enfoque es cambios de código cero a sus servicios - usted simplemente configura HttpClient para señalar el simulacro durante el desarrollo y en la API real en la producción.

// Real code from mostlylucid.net
builder.Services.AddHttpClient<IMarkdownTranslatorService, MarkdownTranslatorService>(
    client => {
        var baseUrl = builder.Configuration["TranslationService:BaseUrl"]
            ?? "http://localhost:5000";  // Mock during dev
        client.BaseAddress = new Uri(baseUrl);
    }
);

appsettings.Development.json:

{
  "TranslationService": {
    "BaseUrl": "http://localhost:5000"  // Mock
  }
}

appsettings.Production.json:

{
  "TranslationService": {
    "BaseUrl": "https://api.production.com"  // Real
  }
}

Este patrón funciona para cualquier HttpClient en tu aplicación - servicios de traducción, pasarelas de pago, APIs externas, lo nombras.

Cuándo usar esto

Antes de sumergirnos en funciones avanzadas, vamos a ser claros sobre cuándo esta herramienta tiene sentido para su flujo de trabajo.

Perfecto para:

  • Desarrollo de la interfaz antes de que exista el motor - Deja de bloquear en los equipos de backend.
  • Pruebas de flujo de trabajo de varios pasos - Memoria de contexto maneja escenarios complejos
  • Prototipado API - Experimente con formas de respuesta antes de comprometerse
  • Desarrollo fuera de línea - Trabajar sin dependencias de red
  • Ensayo de hipótesis de error - Simular fallos sin romper la producción
  • Gasoductos CI/CD - Ninguna dependencia externa significa construcciones más rápidas y fiables

No es ideal para:

  • Entornos de producción - Esta es una herramienta de desarrollo y pruebas
  • Datos de los ensayos determinísticos - Utilice accesorios cuando necesite una reproducibilidad exacta
  • Ensayos de contratos - Validar siempre contra API reales para contratos de producción

Ahora que sabes dónde encaja, exploremos las capacidades avanzadas.

Características avanzadas

Estas características son opcionales - se puede obtener un valor tremendo de lo básico por sí solo. Pero cuando se necesita realismo de grado de producción a escala, estas herramientas están aquí.

Múltiples motores LLM

Guía: Múltiples motores LLM

# Fast for dev
curl http://localhost:5000/api/mock/users

# High quality for demos
curl "http://localhost:5000/api/mock/users?backend=quality"

# Cloud AI for production-like
curl "http://localhost:5000/api/mock/users?backend=openai"

Simulación de limitación de velocidad

Guía: Limitación de velocidad y bateo

Pruebe cómo su aplicación maneja los límites de velocidad:

{
  "EnableRateLimiting": true,
  "RateLimitDelayRange": "500-2000"
}

Simulación de errores

# Test 429 rate limiting
curl "http://localhost:5000/api/mock/users?error=429&errorMessage=Rate%20limit%20exceeded"

# Test 503 unavailable
curl "http://localhost:5000/api/mock/users?error=503"

Soporta todos los códigos 4xx y 5xx.

Caché de respuesta

# Generate and cache 10 variants
curl "http://localhost:5000/api/mock/users?shape={\"$cache\":10,\"id\":0,\"name\":\"string\"}"

Las solicitudes posteriores reciben respuestas en caché instantáneas.

Pruebas de Utilidades: mayormente lucid.mockllmapi.Testing

Paquete: mayormente lucid.mockllmapi.Testing

Todas las características anteriores son ideales para el desarrollo, pero ¿qué pasa con las pruebas automatizadas? El paquete de pruebas acompañante proporciona una API fluida que hace las pruebas de integración una brisa - configurar el comportamiento simulado de manera declarativa y dejar que HttpClient Haz el resto.

Instalación

dotnet add package mostlylucid.mockllmapi.Testing

Uso básico

using mostlylucid.mockllmapi.Testing;

// Create a client with a single endpoint configuration
var client = HttpClientExtensions.CreateMockLlmClient(
    baseAddress: "http://localhost:5116",
    pathPattern: "/users",
    configure: endpoint => endpoint
        .WithShape(new { id = 0, name = "", email = "" })
        .WithCache(5)
);

// Make requests - configuration is automatically applied
var response = await client.GetAsync("/users");
var users = await response.Content.ReadFromJsonAsync<User[]>();

Múltiples puntos finales

var client = HttpClientExtensions.CreateMockLlmClient(
    "http://localhost:5116",
    configure: handler => handler
        .ForEndpoint("/users", config => config
            .WithShape(new { id = 0, name = "", email = "" })
            .WithCache(10))
        .ForEndpoint("/posts", config => config
            .WithShape(new { id = 0, title = "", content = "", authorId = 0 })
            .WithCache(20))
        .ForEndpoint("/error", config => config
            .WithError(404, "Resource not found"))
);

// Each endpoint automatically uses its configuration
var usersResponse = await client.GetAsync("/users");
var postsResponse = await client.GetAsync("/posts");
var errorResponse = await client.GetAsync("/error"); // Returns 404

Opciones de configuración

Configuración de la forma:

// Using anonymous objects
.WithShape(new { id = 0, name = "", active = true })

// Using JSON strings
.WithShape("{ \"id\": 0, \"name\": \"\", \"tags\": [] }")

// Complex nested structures
.WithShape(new
{
    user = new { id = 0, name = "" },
    posts = new[] { new { id = 0, title = "" } }
})

Simulación de errores:

// Simple error
.WithError(404)

// With custom message
.WithError(404, "User not found")

// With details
.WithError(422, "Validation failed", "Email address is invalid")

Streaming:

// Enable streaming with token-by-token output
.WithStreaming()
.WithSseMode("LlmTokens")

// Stream complete objects
.WithStreaming()
.WithSseMode("CompleteObjects")

// Stream array items individually
.WithStreaming()
.WithSseMode("ArrayItems")

Inyección por dependencia

Cliente tecleado:

services.AddMockLlmHttpClient<IUserApiClient>(
    baseApiPath: "/api/mock",
    configure: handler => handler
        .ForEndpoint("/users", config => config
            .WithShape(new { id = 0, name = "", email = "" }))
);

Nombre del cliente:

services.AddMockLlmHttpClient(
    name: "MockApi",
    baseApiPath: "/api/mock",
    configure: handler => handler
        .ForEndpoint("/data", config => config
            .WithShape(new { value = 0 }))
);

// Usage
var client = httpClientFactory.CreateClient("MockApi");

Ejemplo de pruebas de integración

[Fact]
public async Task Should_Handle_User_Creation()
{
    // Arrange
    var client = HttpClientExtensions.CreateMockLlmClient(
        "http://localhost:5116",
        "/users",
        config => config
            .WithMethod("POST")
            .WithShape(new { id = 0, name = "", email = "", createdAt = "" })
    );

    // Act
    var newUser = new { name = "John Doe", email = "[email protected]" };
    var response = await client.PostAsJsonAsync("/users", newUser);

    // Assert
    response.EnsureSuccessStatusCode();
    var created = await response.Content.ReadFromJsonAsync<User>();
    Assert.NotNull(created);
    Assert.NotEqual(0, created.Id);
}

[Fact]
public async Task Should_Handle_Not_Found_Error()
{
    // Arrange
    var client = HttpClientExtensions.CreateMockLlmClient(
        "http://localhost:5116",
        "/users/999",
        config => config.WithError(404, "User not found")
    );

    // Act
    var response = await client.GetAsync("/users/999");

    // Assert
    Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}

Cómo funciona

Los MockLlmHttpHandler es una DelegatingHandler que:

  1. Intercepta las solicitudes HTTP salientes
  2. Coincide con las peticiones contra los patrones de endpoint configurados
  3. Inyecta configuración simulada a través de parámetros de consulta y encabezados HTTP
  4. Reenvía la solicitud modificada a la API de LLM simulada real

Esto le permite utilizar un real HttpClient en sus pruebas mientras controla fácilmente el comportamiento de la API simulada sin modificar el código de la aplicación.

Mejores prácticas y consejos

Después de trabajar con esta herramienta en múltiples proyectos, aquí están los patrones que funcionan mejor:

  1. Usar siempre contextos para flujos de trabajo - Garantiza identificaciones y datos consistentes a través de operaciones multi-paso
  2. Forma de uso para la seguridad del tipo - Haz que coincida con tus interfaces TypeScript
  3. Mezclar datos reales y simulados con herramientas - Lo mejor de ambos mundos
  4. Elija el modelo correcto (véase Guía de modelos de Ollama Para más detalles:
    • RECOMENDADO PARA EL DEV: ministral-3:3b (3B params, 32K context) - ¡Matar a JSON! RAM ultrarrápida, altamente precisa y mínima
    • Producción-como: llama3 (8B params, 8K context) - El mejor equilibrio de calidad y rendimiento
    • Alta calidad: mistral-nemo (12B params, 128K context) - Esquemas complejos y conjuntos de datos masivos
    • Recursos limitados: gemma3:4b o phi3 - Alternativas más ligeras

Documentación completa

Conclusión

El desarrollo de Frontend no tiene que esperar a las API de backend. mostlylucid.mockllmapi le da:

  • Memoria de contexto - Datos consistentes y confiables a través de flujos de trabajo de varios pasos
  • Control de forma - Definiciones precisas de esquemas que coincidan con sus tipos
  • Apoyo al protocolo universal - REST, GraphQL, GRPC, SignalR, SSE, OpenAPI
  • Ensayos híbridos - Mezclar datos de producción reales con simulacros generados
  • Mantenimiento cero - No hay accesorios JSON para actualizar cuando cambian los requisitos
  • Utilidades de ensayo - API de fluidez para pruebas de integración

¿La diferencia entre esto y la burla tradicional? Su interfaz funciona contra datos realistas, contextualmente conscientes desde el primer día. No más "funcionó con datos simulados pero falló con datos reales" sorpresas.

Ya sea que estés construyendo un blog simple o una aplicación empresarial compleja, iterarás más rápido, probarás más a fondo y enviarás con confianza.

¿Listo para empezar?

docker compose up -d

Eso es, no se requiere motor.

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.