¿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.
Usted puede utilizar principalmentelucid.mockllmapi de tres maneras, dependiendo de lo aislado que desee que su entorno dev sea:
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:
Comportamiento:
Seguridad:
Casos de uso:
dotnet add package mostlylucid.mockllmapi
// Program.cs
builder.Services.AddLLMockApi(builder.Configuration);
app.MapLLMockApi("/api/mock");
# Download from https://github.com/scottgal/LLMApi/releases
llmock serve --port 5000
Guía completa: Guía de implementación de Docker
git clone https://github.com/scottgal/LLMApi.git
cd LLMApi
docker compose up -d
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.
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.
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.
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.
# 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:
?shape={...}X-Response-Shape: {...} (recomendado){"shape": {...}}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) }
});
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!
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.
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:
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.
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}'
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.
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
};
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
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.
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.
Antes de sumergirnos en funciones avanzadas, vamos a ser claros sobre cuándo esta herramienta tiene sentido para su flujo de trabajo.
Perfecto para:
No es ideal para:
Ahora que sabes dónde encaja, exploremos las capacidades 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í.
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"
Pruebe cómo su aplicación maneja los límites de velocidad:
{
"EnableRateLimiting": true,
"RateLimitDelayRange": "500-2000"
}
# 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.
# 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.
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.
dotnet add package mostlylucid.mockllmapi.Testing
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[]>();
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
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")
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");
[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);
}
Los MockLlmHttpHandler es una DelegatingHandler que:
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.
Después de trabajar con esta herramienta en múltiples proyectos, aquí están los patrones que funcionan mejor:
ministral-3:3b (3B params, 32K context) - ¡Matar a JSON! RAM ultrarrápida, altamente precisa y mínimallama3 (8B params, 8K context) - El mejor equilibrio de calidad y rendimientomistral-nemo (12B params, 128K context) - Esquemas complejos y conjuntos de datos masivosgemma3:4b o phi3 - Alternativas más ligerasEl desarrollo de Frontend no tiene que esperar a las API de backend. mostlylucid.mockllmapi le da:
¿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.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.