Établissement d’une interface avant que l’API ne soit prête: Sans appareils fixes
Introduction
Combien de fois avez-vous été bloqués en attendant que les API du backend soient prêts? Ou passé des heures à entretenir des données prototypes fragiles qui sont devenues nulles au moment où les exigences changent?
Inscrire mostlylucid.mockllmapi - une production- ASP prête à fonctionner . plateforme de simulation du noyau réseau qui utilise les grands modèles langagiques pour produire des réponses API réalistes sur le plan contextuelM SK3 vous obtiendrez des simulations intelligentes qui s’adaptent à vos demandes et se souviendront de l’état d’ensemble des appels.
Ce qu'il appuie: Tous les protocoles dont vous avez besoin - RESTM SK1 GraphQL, gRPC , SignalRMST4 ServerMSC5Sent EventsMNK6 and OpenAPIMRK7 Contrairement aux dispositifs fixes statiques, les réponses sont générées dynamiquement en fonction du contexte de votre demande.
Liens du projet
- Répositoire: https://github.com /scottgalM SK3LLMApi
- Rejets: https://github.com /scottgalM SK3LLMApiMSC4releases
- Companion Package: mostlylucid.mockllmapiM SK1Testing - Utilisations d'essai avec une intégration HttpClient fluide
Trois façons d'en utiliser
Vous pouvez utiliser le plus souventlucid.mockllmapi de trois façons, selon la mesure dans laquelle vous voulez que votre environnement dev soit isolé
- ASP.NET Core NuGet package - Ajouter à vos projets existants
- Outil CLI autonome -Cross-platform exécutable (download de autorisations de mise en liberté)
- Contenant Docker - Installation zéro requise
La fonctionnalité Killer: Mémoire de contexte
📖 Guide completM SK1 Contextes de l'API Documentation
Les API modèles traditionnels présentent un défaut fatal: chaque demande est indépendante. Obtenez un utilisateur avec l'ID 42, puis reçoisez ses commandesM SK3 et vousMSC4 obtiendrez des commandes pour l'identité de l'utilisateur MNK5 Aucune cohérenceMRK6
Contextes de l'API résoudre ce problème avec une mémoire partagée à travers des demandes connexes:
// 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
Le LLM voit les demandes antérieures dans le même contexte et produit des données cohérentes. Il s’agit du jeu-changer pour les flux de travail à plusieurs étapes
Caractéristiques:
cycle de vie:
- Expiration automatique après 15 minutes d'inactivité (configurable)
- Chaque demande actualise le temps-temps
Comportement:
- Extraction intelligente de TOUS les champs des réponses
Sécurité:
- Nulle fuite de mémoire Les contextes - se nettoient eux-mêmes
Utiliser les cases:
- Perfect pour CI/CD - aucun état entre les exécutions
Démarrage rapide
Option 1: NuGet Package
dotnet add package mostlylucid.mockllmapi
// Program.cs
builder.Services.AddLLMockApi(builder.Configuration);
app.MapLLMockApi("/api/mock");
Option 2: Outil CLI
# Download from https://github.com/scottgal/LLMApi/releases
llmock serve --port 5000
Option 3: Docker
📖 Guide complet : Guide de déploiement du Docker
git clone https://github.com/scottgal/LLMApi.git
cd LLMApi
docker compose up -d
Exigences préalables: LLM Backend
Vous avez besoin un des: OllamaM SK1 OpenAI , ou Studio LM:
# Recommended: Ollama with ministral-3:3b (ultra-fast, accurate JSON generation)
ollama pull ministral-3:3b
Voir Guide des modèles Ollama pour toutes les recommandations et comparaisons du modèle.
Essayez immédiatement
Une fois lancée, faites votre première demande:
curl http://localhost:5000/api/mock/users
# Response: [{"id": 1, "name": "Alice Johnson", "email": "[email protected]"}, ...]
Que'c'est ce qu'il est! Vous avez maintenant un modèle d'API fonctionnel qui génère des données réalistes sur demande
Exemple réelle: Recherche de mostlylucid.net
Voici le code de recherche réel de ce blog - c'est un code de production frontend inchangé, Aucune adaptation n'est nécessaire pour le modèle
// 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; });
}
}
}
Je ne sais pas.
# 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
Chaque réponse est unique et réaliste, adaptée à la demande.
Contrôle de la forme: Définir votre schéma
Outre la simple production de données aléatoires, vous avez souvent besoin d’un contrôle précis sur la structure JSON.
Forme de base
# 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]" }
Trois façons de spécifier la forme:
- Paramètre de la demande -
?shape={...} - Intitulé HTTP -
X-Response-Shape: {...}(recommandéM SK1 - Organe de demande -
{"shape": {...}}
Forme en positionnement
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) }
});
L'alignement 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!
Multi-Step Workflows with Context
Maintenant, laissez's combiner le contrôle de la forme avec les contextes API pour traiter des tâches complexes , multi-flows de travail à étapes. Rappelez-vous de l’aspect mémoire contextuelle qui vous a été présenté plus tôtMSC4 VoiciM SK5 comment il brille en réalitéMNK6opérations asynchrones du monde\MNK7
Cet exemple du service de traduction de mostlylucid.net' montre comment le LLM maintient l’état dans un flux de travail async complet
# 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" }
Veuillez noter comment taskId est uniforme dans toutes les demandes. Contexte rend cela possible.
Au-delà de REST: Tous les protocoles
Jusqu’à présent, nous' avons mis l’accent sur le REST , mais les applications modernes ont besoin de plus. Que vousM SK3 construisez avec GraphQLMSC4 mettez en oeuvre des fonctions réellesMST5 temps avec SignalRMSP6 ou travaillez avec les services gRPCMSV7 la plupartlucidMSS8mockllmapi vous a couvertMSST9
Protocoles supportés:
- ✓ REST
- ✓ GraphQL
- ✓ gRPC
- ✓ SignalR
- ✓ ServeurM SK1 Événements envoyés (SSE)
- ✓ OpenAPI / Swagger
GraphQL
📖 Guide Section GraphQL
curl -X POST http://localhost:5000/api/mock/graphql \
-d '{"query": "{ users { id name email } }"}'
La demande est la forme - aucun schéma distinct n'est requis.
gRPC
📖 Guide complet : Soutien 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}'
SignalR Real-Time
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");
Perfect pour le prototypage du tableau de bord.
Server-Sent Events (SSEM SK2
📖 Guide Modes d'écoulement 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
};
Swagger OpenAPI /
📖 Guide complet : Fonctions de l'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
Outils pluggables: Mélanger des données réelles & Mock Data
📖 Guide complet : Outils & Actions
Parfois, vous avez besoin d’une approche hybride - des données réelles provenant de la production combinées à celles produites dans le cadre d’un projet pilote . Le système d’outils pluggables vous permet d’appeler les APIs réels pendant la création du projet prototype, en créant des scénarios d’essai incroyablement réalistesM SK3
{
"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"
Le modèle reçoit les données de l’utilisateur REAL, puis le LLM génère des commandes en utilisant ce dernier. Extrêmement utile pour des essais réalistes avec un modèle hybride/flows de travail réels.
ASP.Intégration du noyau NET
Si vous construisez avec ASP, ., Core NET et ,, l’intégration est sans fil. Aucun changement de code à vos services - vous pouvez simplement configurer HttpClient de mettre en évidence le modèle au cours du développement et l’API réel dans la production.
// 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.jsonM SK2
{
"TranslationService": {
"BaseUrl": "http://localhost:5000" // Mock
}
}
appsettings.ProductionM SK1json:
{
"TranslationService": {
"BaseUrl": "https://api.production.com" // Real
}
}
Ce modèle fonctionne pour n'importe quel HttpClient dans votre application - services de traduction , passerelles de paiement, API externesM SK3 le nom que vous donnez à ce type d’application
Quand utiliser ce fichier
Avant de nous plonger dans les fonctionnalités avancées, laissez-nous savoir quand cet outil a sens pour votre travailflow.
Perfect pour:
- Développement de frontend avant que le backend n'existe - Supprimer le blocage sur les équipes de backend
- Évaluation du flux de travail à plusieurs étapes - La mémoire contextuelle gère des scénarios complexes
- Fabrication de prototypes d'API - Expérimenter les formes de réponse avant d’engager
- Développement hors ligne - Travailler sans dépendance de réseau
- Évaluation du scénario d'erreur - Simulation des défaillances sans rompre la production
- Pipelines CI/CD - Aucune dépendance externe signifie une construction plus rapide , plus fiable
Pas idéal pour:
- Environnements de production - C'est un outil de développement et d'essai
- Données d'essai déterministes - Utilisez les accessoires lorsque vous avez besoin d'une reproductibilité exacte
- Évaluation des contrats - Valider toujours par rapport aux API réels pour les contrats de production
Maintenant que vous savez où il convient, , laissez ' explorer les capacités avancées.
Caractéristiques avancées
Ces fonctionnalités sont facultatives - vous pouvez obtenir une valeur extraordinaire à partir des éléments de base seuls . Mais lorsque vous avez besoin d’une production- un réalisme de niveau à l’échelleM SK3 ces outils sont iciMSC4
Multiple LLM Backends
📖 Guide Multiple LLM Backends
# 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"
Simulation de la limite du taux
📖 Guide Limitation du taux & Battage
Vérifiez comment votre application gère les limites de vitesse:
{
"EnableRateLimiting": true,
"RateLimitDelayRange": "500-2000"
}
Simulation d'une erreur
# 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"
Appuie tous les codes 4xx et 5xx
Cache des réponses
# Generate and cache 10 variants
curl "http://localhost:5000/api/mock/users?shape={\"$cache\":10,\"id\":0,\"name\":\"string\"}"
Requêtes subséquentes reçoivent des réponses cachées instantanées.
Utilités d'essai: mostlylucid.mockllmapiM SK2Testing
📖 PackageM SK1 mostlylucid.mockllmapiM SK1Testing
Tous les éléments susmentionnés sont excellents pour le développement, mais que dire de l’essai automatisé? Le paquet d’essais conjoint fournit une API fluide qui fait des essais d’intégration une brise M SK2 configurer le comportement de modèle de façon déclarative et laisser HttpClient faire le reste.
Installation
dotnet add package mostlylucid.mockllmapi.Testing
Usage de base
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[]>();
Plusieurs points de fin
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
Options de configuration
Configuration de la forme:
// 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 = "" } }
})
Simulation de l'erreur:
// 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")
Injection de dépendance
Client typed:
services.AddMockLlmHttpClient<IUserApiClient>(
baseApiPath: "/api/mock",
configure: handler => handler
.ForEndpoint("/users", config => config
.WithShape(new { id = 0, name = "", email = "" }))
);
Client dénommé:
services.AddMockLlmHttpClient(
name: "MockApi",
baseApiPath: "/api/mock",
configure: handler => handler
.ForEndpoint("/data", config => config
.WithShape(new { value = 0 }))
);
// Usage
var client = httpClientFactory.CreateClient("MockApi");
Exemple d'analyse de l'intégration
[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);
}
Comment cela fonctionne
L'article 5 de la Loi sur l'immigration et le statut des réfugiés MockLlmHttpHandler est un DelegatingHandler que:
- Intercepter les demandes HTTP sortantes
- Correspond aux demandes contre les modèles de point final configurés
- Injecter la configuration de modèle par l'entremise des paramètres de demande et des titres HTTP
- Passer la demande modifiée à l'API de modèle LLM réel
Cela vous permet d'utiliser un HttpClient dans vos tests tout en contrôlant facilement le comportement de l’API modèle sans modifier votre code d’application.
Pratiques exemplaires & Conseils
Après avoir travaillé avec cet outil dans plusieurs projets, voici les modèles qui fonctionnent le mieux.
- Utiliser toujours des contextes pour les flux de travail - Assure des ID et des données cohérentes dans les opérations à plusieurs étapes
- Utiliser la forme pour assurer la sécurité du type - Faites-le correspondre à vos interfaces TypeScript
- Mélanger des données réelles et modèles avec les outils - Le meilleur des deux mondes
- Choisissez le modèle approprié (voir Guide des modèles Ollama pour plus de détails):
- RECOMMENDED pour dev:
ministral-3:3b(3B par. KILLER pour JSON! Ultra-fast,extrêmement précisM SK2 RAM minimal - Production-comme:
llama3(8B paramsM SK1 8Contexte de la K) - Le meilleur équilibre entre qualité et rendement - Qualité élevée:
mistral-nemo(12B paramètresM SK1 128Contexte de K) ≥- Systèmes complexes et ensembles de données massifs - Ressource-constrérée:
gemma3:4bouphi3- Solutions de rechange plus légers
- RECOMMENDED pour dev:
Documentation complète
- Référentiel principal - Source et aperçu
- Référence de configuration - Tous les paramètres
- Guide des contextes de l'API - immersion profonde de la mémoire contextuelle
- Outils & Actions - Intégration externe de l'API
- Fonctions de l'OpenAPI - Spec- mocking basé sur
- Soutien gRPC - Buffers de protocole
- Guide du docker - Déploiement de conteneurs
- Multiple Backends Établissement de fournisseurs - Multi-
- Limitation du taux - Simulation des limites
- Évaluation du paquet - HttpClient utilities
Conclusion
Le développement de frontend n’a pas à attendre les APIs de backend' mostlylucid.mockllmapi vous donne:
- Mémoire de contexte - Données cohérentes , exactes sur plusieurs étapes de travail
- Contrôle de la forme - Définitions précises du schéma qui correspondent à vos types
- Soutien du protocole universel - REST, GraphQL, gRPCM SK3 SignalRMska4 SSEM Ska5 OpenAPI
- Essais hybrides - Mélanger les données de production réelles avec des modèles générés
- Maintien zéro - Aucune installation JSON à mettre à jour lorsque les exigences changent
- Utilités d'essai - API Fluent pour les essais d'intégration
La différence entre ce et le mocking traditionnel? Votre frontend fonctionne contre les données réalistes , des données concrètement conscientes depuis le premier jourM SK2 Pas plus " il a travaillé avec des données de simulation mais n'a pas réussi avec les données realesMST4 surprises MST5
Que vous construisez un simple blog ou une application d’entreprise complexe, ,, vous iterez plus rapidement,,, testez de façon plus approfondie,, et expédiez avec confiance.
Préparé pour commencer?
docker compose up -d
Que'c'est ça. Aucun backend requisM SK2