Quante volte sei stato bloccato aspettando che le API del backend fossero pronte? O hai passato ore a mantenere i dati sfrenati che diventano stantii i cambiamenti dei requisiti del momento?
Entra mostlylucid.mockllmapi - una piattaforma di derisione ASP.NET Core pronta alla produzione che utilizza modelli di lingua larga per generare risposte API realistiche e contestuali al volo. Invece di mantenere i dispositivi JSON, si ottengono derisioni intelligenti che si adattano alle vostre richieste e ricordare lo stato attraverso le chiamate.
Cosa sostiene: Ogni protocollo di cui hai bisogno - REST, GraphQL, gRPC, SignalR, Server-Sent Events e OpenAPI. A differenza dei dispositivi statici, le risposte vengono generate dinamicamente in base al contesto richiesto, rendendo banali flussi di lavoro multi-step e scenari di test complessi.
È possibile utilizzare principalmentelucid.mockllmapi in tre modi, a seconda di quanto isolato si desidera che il vostro ambiente dev essere:
Guida completa: Documentazione sui contesti delle API
Le API tradizionali hanno un difetto fatale: ogni richiesta è indipendente. Ottieni un utente con ID 42, quindi prendi i loro ordini, e riceverai ordini per ID utente 99. Nessuna consistenza.
Contesto delle API risolvere questo problema con la memoria condivisa attraverso le relative richieste:
// 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
La LLM vede richieste precedenti nello stesso contesto e genera dati coerenti. Questo è il cambio di gioco per i flussi di lavoro multi-step.
Caratteristiche:
Ciclo di vita:
Comportamento:
Sicurezza:
Casi di utilizzo:
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
Guida completa: Guida alla distribuzione dei docker
git clone https://github.com/scottgal/LLMApi.git
cd LLMApi
docker compose up -d
Hai bisogno di uno di: Ollama, OpenAI, o LM Studio:
# Recommended: Ollama with ministral-3:3b (ultra-fast, accurate JSON generation)
ollama pull ministral-3:3b
Vedi Guida ai modelli di Ollama per tutti i modelli di raccomandazioni e confronti.
Una volta eseguito, effettuare la prima richiesta:
curl http://localhost:5000/api/mock/users
# Response: [{"id": 1, "name": "Alice Johnson", "email": "[email protected]"}, ...]
Ecco! Ora hai una finta API funzionante che genera dati realistici su richiesta.
Ecco il codice di ricerca reale da questo blog - Questo è codice di frontend di produzione inalterato, nessun adattamento necessario per la simulazione:
// 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; });
}
}
}
Muoviti!
# 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
Ogni risposta è unica e realistica, adattandosi alla query.
Oltre a generare dati casuali, è spesso necessario un controllo preciso sulla struttura JSON. Il controllo della forma consente di dire all'LLM esattamente quale struttura generare - la caratteristica più potente per lo sviluppo del 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]" }
Tre modi per specificare la forma:
?shape={...}X-Response-Shape: {...} (raccomandato){"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!
Ora combiniamo il controllo della forma con i contesti API per gestire i flussi di lavoro complessi e multi-step. Ricordate la funzione di memoria contestuale di prima? Ecco come brilla nelle operazioni asincrone del mondo reale.
Questo esempio dal servizio di traduzione per lo piùlucid.net mostra come l'LLM mantiene lo stato attraverso un flusso di lavoro completo asincrono:
# 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" }
Nota come taskId è coerente con tutte le richieste. Il contesto lo rende possibile.
Finora ci siamo concentrati su REST, ma le applicazioni moderne hanno bisogno di più. Che tu stia costruendo con GraphQL, implementando funzionalità in tempo reale con SignalR, o lavorando con i servizi gRPC, per lo piùlucid.mockllmapi ti ha coperto.
Protocolli supportati:
Guida: Sezione GraficoQL
curl -X POST http://localhost:5000/api/mock/graphql \
-d '{"query": "{ users { id name email } }"}'
La query è la forma - non è necessario uno schema separato.
Guida completa: Supporto 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}'
Guida: Guida demo 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");
Perfetto per la prototipazione del cruscotto.
Guida: Modalità di streaming 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
};
Guida completa: Funzionalità 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
Guida completa: Strumenti e azioni
A volte è necessario un approccio ibrido - i dati reali dalla produzione combinata con i dati mock generati. Il sistema di strumenti pluggable consente di chiamare API reali durante la generazione mock, creando scenari di test incredibilmente realistici.
{
"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"
Il mock recupera i dati utente REAL, quindi l'LLM genera ordini usandolo. Estremamente utile per test realistici con flussi di lavoro ibridi simulati/reali.
Se si sta costruendo con ASP.NET Core, l'integrazione è senza soluzione di continuità. La bellezza di questo approccio è nessuna modifica del codice ai tuoi servizi - puoi semplicemente configurare HttpClient per indicare il mock durante lo sviluppo e la vera API in produzione.
// 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);
}
);
Appettings. Development.json:
{
"TranslationService": {
"BaseUrl": "http://localhost:5000" // Mock
}
}
appsettings.Production.json:
{
"TranslationService": {
"BaseUrl": "https://api.production.com" // Real
}
}
Questo modello funziona per qualsiasi HttpClient nella tua applicazione - servizi di traduzione, gateway di pagamento, API esterne, lo nomini.
Prima di tuffarci nelle funzionalità avanzate, cerchiamo di essere chiari su quando questo strumento ha senso per il vostro flusso di lavoro.
Perfetto per:
Non ideale per:
Ora che sai dove si trova, esploriamo le capacità avanzate.
Queste caratteristiche sono opzionali - si può ottenere un enorme valore dalle basi da soli. Ma quando avete bisogno di realismo di produzione a scala, questi strumenti sono qui.
Guida: Backend LLM multipli
# 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"
Verifica come la tua app gestisce i limiti di velocità:
{
"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"
Supporta tutti i codici 4xx e 5xx.
# Generate and cache 10 variants
curl "http://localhost:5000/api/mock/users?shape={\"$cache\":10,\"id\":0,\"name\":\"string\"}"
Le richieste successive ottengono risposte cache istantanee.
Pacchetto di galattosio: per lo piùlucid.mockllmapi.Test
Tutte le caratteristiche di cui sopra sono grandi per lo sviluppo, ma che dire di test automatizzati? Il pacchetto test compagno fornisce una fluente API che rende l'integrazione test una brezza - configurare il comportamento finto dichiarativo e lasciare HttpClient Fai il 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
Configurazione 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 = "" } }
})
Simulazione errori:
// 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")
Client digitato:
services.AddMockLlmHttpClient<IUserApiClient>(
baseApiPath: "/api/mock",
configure: handler => handler
.ForEndpoint("/users", config => config
.WithShape(new { id = 0, name = "", email = "" }))
);
Client con nome:
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);
}
La MockLlmHttpHandler è un DelegatingHandler che:
Questo consente di utilizzare un reale HttpClient nei tuoi test controllando facilmente il comportamento delle API simulate senza modificare il codice dell'applicazione.
Dopo aver lavorato con questo strumento su più progetti, ecco i modelli che funzionano meglio:
ministral-3:3b (3B params, 32K context) - Killer per Json! RAM ultra-veloce, altamente accurata, minimalellama3 (8B params, contesto 8K) - Miglior equilibrio di qualità e prestazionimistral-nemo (12B params, 128K context) - Schemi complessi e set di dati di massagemma3:4b oppure phi3 - Alternative più leggereLo sviluppo di Frontend non deve aspettare le API di backend. mostlylucid.mockllmapi ti dà:
La differenza tra questo e il scherno tradizionale? Il tuo frontend funziona contro i dati realistici e contestualmente consapevoli fin dal primo giorno. Niente più "ha funzionato con i dati finti ma non è riuscito con i dati reali" sorprese.
Che tu stia costruendo un blog semplice o un'applicazione enterprise complessa, itererai più velocemente, testerai più accuratamente e spedirai con fiducia.
Pronto per iniziare?
docker compose up -d
Niente backend richiesto.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.