Frontendin rakentaminen ennen kuin sovellusrajapinta on valmis: ilman kompuroivia korjauksia (Suomi (Finnish))

Frontendin rakentaminen ennen kuin sovellusrajapinta on valmis: ilman kompuroivia korjauksia

Saturday, 13 December 2025

//

13 minute read

Johdanto

Monestiko sinua on estetty odottamasta, että backend API on valmis? Tai viettänyt tunteja säilyttäen haurasta valedataa, josta tulee tunkkaista, kun vaatimukset muuttuvat?

Syötä mostlylucid.mockllmapi - tuotantovalmiin ASP.NET Core -pilkkualustan, joka käyttää Large Language Modelsia tuottaakseen realistisia, kontekstillisesti tietoisia API-vastauksia lennossa. Sen sijaan, että pitäisit yllä JSON-laitteita, saat älykkäitä mokia, jotka mukautuvat pyyntöihisi ja muistavat tilan eri puheluissa.

Se, mitä se tukee: Kaikki tarvitsemasi protokollat - REST, GraphQL, gRPC, SignalR, Server-Sent Events ja OpenAPI. Toisin kuin staattiset kalusteet, vastaukset syntyvät dynaamisesti pyyntökontekstisi perusteella, mikä tekee monivaiheisista työvirroista ja monimutkaisista testausskenaarioista vähäpätöisiä.

Projektin linkit

NuGet NuGet GitHub-julkaisu Lisenssi: Luvaton

Kolme tapaa käyttää sitä

Voit käyttää enimmäkseen lucid.mockllmapia kolmella tavalla riippuen siitä, kuinka eristyksissä haluat dev-ympäristösi olevan:

  1. ASP.NET Core NuGet -paketti - Lisää olemassa oleviin projekteihisi
  2. Erillinen CLI-työkalu - Cross-platform-suoritetiedosto (ladattava tiedotteet)
  3. Kuorma-auton kontti - Asennuksia ei tarvita

Tappajan ominaisuus: Kontekstimuisti

Koko opas: API-kontekstien dokumentointi

Perinteisessä pilkun sovellusrajapinnassa on kohtalokas vika: jokainen pyyntö on riippumaton. Hanki käyttäjä, jolla on tunniste 42, ja nouta heidän tilauksensa, ja saat tilaukset käyttäjätunnuksesta 99. Ei johdonmukaisuutta.

API-kontekstit Ratkaise tämä yhteisellä muistilla eri pyyntöjen välillä:

// 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

LLM näkee aiemmat pyynnöt samassa yhteydessä ja tuottaa johdonmukaisia tietoja. Tämä on monivaiheisten työnkulkujen pelinvaihtaja.

Ominaisuudet:

Elinkaari:

  • Automaattinen vanheneminen 15 minuutin toimettomuuden jälkeen (konfiguroitava)
  • Jokainen pyyntö virkistää ajastinta

Käyttäytyminen:

  • ALL-kenttien älykäs poimiminen vastauksista

Turvallisuus:

  • Nolla muistivuotoa - kontekstit siistiytyvät

Käytä tapauksia:

  • Täydellinen CI/CD:lle - ei tilaa juoksujen välillä

Pikakäynnistys

Vaihtoehto 1: NuGet-paketti

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

Vaihtoehto 2: CLI-työkalu

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

Vaihtoehto 3: Docker

Täydellinen opas: Dockerin käyttöönottoopas

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

Edeltävät opinnot: LLM Backend

Tarvitset yksi: Ollama, OpenAI tai LM Studio:

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

Katso Ollaman malliopas kaikkien mallisuositusten ja -vertailujen osalta.

Kokeile heti

Kun olet juossut, tee ensimmäinen pyyntösi:

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

Nyt sinulla on toimiva pilkkurajapinta, joka tuottaa realistista dataa kysynnästä.

Todellinen esimerkki: Hae osoitteesta moderallucid.net

Tässä varsinainen hakukoodi tästä blogista - tämä on muuttumaton tuotannon etukäteiskoodi, mokaan ei tarvita mukautuksia:

// 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; });
        }
    }
}

Pilkkaa se:

# 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

Jokainen vastaus on ainutlaatuinen ja realistinen, ja se mukautuu kyselyyn.

Muotoilun ohjaus: Määrittele aivohalvaus

Satunnaisen datan tuottamisen lisäksi tarvitaan usein tarkkaa JSON-rakenteen hallintaa. Muodonohjauksen avulla voidaan kertoa LLM:lle, mikä rakenne tarkalleen ottaen tuottaa - tehokkain ominaisuus etuosan kehittämiseen.

Perusmuoto

# 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]" }

Kolme tapaa määritellä muoto:

  1. Kyselyparametri - ?shape={...}
  2. HTTP:n otsikko - X-Response-Shape: {...} (suositeltu)
  3. Pyynnön esittänyt elin {"shape": {...}}

Nestedin muoto

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) }
});

TypeScriptin kohdistaminen

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!

Monivaiheisia työvirtoja kontekstin kanssa

Nyt yhdistetään muodonhallinta API-yhteyksiin ja käsitellään monimutkaisia, monivaiheisia työnkulkuja. Muistatko aiemman kontekstimuistin? Näin se loistaa tosimaailman asynkronisissa toiminnoissa.

Tämä esimerkki suurimmaksi osaksi lucid.netin käännöspalvelusta osoittaa, kuinka LLM ylläpitää tilaa läpi täydellisen async-työnkulun:

# 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" }

Huomaa, miten taskId on johdonmukainen kaikissa pyynnöissä. Konteksti mahdollistaa tämän.

REST:n lisäksi: Kaikki pöytäkirjat

Tähän mennessä olemme keskittyneet RESTiin, mutta modernit sovellukset tarvitsevat lisää. Rakensitpa sitten GraphQL:llä, toteutit reaaliaikaisia ominaisuuksia SignalR:llä tai työskentelit gRPC-palveluiden kanssa, enimmäkseen lucid.mockllmapi on hoitanut sinut.

Tuetut protokollat:

  • . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  • â € € # GrafQL
  • â € ~ gRPC
  • Palvelimen lähettämät tapahtumat (SSE)
  • OpenAPI / Swagger

GrafQL

Oppaat: GrafQL-osio

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

Kysymys IS on muoto - erillistä skeemaa ei tarvita.

gRPC

Täydellinen opas: gRPC-tuki

# 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 reaaliajassa

Oppaat: SignalR Demo Guide

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");

Täydellinen kojelautaprototyypitykseen.

Palvelimen lähettämät tapahtumat (SSE)

Oppaat: SSE:n virtaukset

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

Täydellinen opas: OpenAPI-ominaisuudet

# 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

Kytkettävät työkalut: Sekoita Real & Mock Data

Täydellinen opas: Työkalut ja toimet

Joskus tarvitaan hybridilähestymistapaa - todellista dataa tuotannosta yhdistettynä tuotettuun valetietoon. Liitännäistyökalujärjestelmän avulla voit soittaa varsinaisia sovellusliittymiä valesukupolven aikana ja luoda uskomattoman realistisia testiskenaarioita.

{
  "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"

Mokka hakee todellista käyttäjätietoa, minkä jälkeen LLM tuottaa tilauksia sitä käyttäen. Erittäin hyödyllinen realistiseen testaukseen hybridimokalla/todellisella työnkululla.

ASP.NET Core Integration

Jos rakennat ASP.NET Corella, integraatio on saumatonta. Tämän lähestymistavan kauneus on nollakoodin muutokset palveluihisi - voit yksinkertaisesti konfiguroida HttpClient osoittaa mokia kehityksen aikana ja todellisesta API-rajapinnasta tuotannossa.

// 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);
    }
);

Asetukset.Kehitys.Json:

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

Asetukset.Tuotanto.json:

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

Tämä malli toimii kaikille HttpClient hakemuksessasi - käännöspalveluissa, maksukanavissa, ulkoisissa sovellusliittymissä, mitä tahansa.

Milloin tätä käytetään

Ennen kuin sukellamme kehittyneisiin ominaisuuksiin, tehdään selväksi, milloin tämä työkalu on mielekäs työnkulkusi kannalta.

Täydellinen:

  • Frontend-kehitys ennen backendiä - Lopeta backend-tiimien estäminen
  • Monivaiheisen työnkulun testaus - Kontekstimuisti käsittelee monimutkaisia skenaarioita
  • API-prototyypitys - Kokeile vasteen muotoja ennen kuin sitoudut
  • Offline-kehitys - Työ ilman verkon riippuvuuksia
  • Virheskenaarion testaus - Simuloi epäonnistumisia rikkomatta tuotantoa
  • CI/CD-putket - Ei ulkoisia riippuvuuksia tarkoittaa nopeampaa ja luotettavampaa rakentamista

Ei ihanteellinen:

  • Tuotantoympäristöt - Tämä on kehitys- ja testaustyökalu
  • Määritteleviä testitietoja - Käytä varusteita, kun tarvitset tarkan toistettavuuden
  • Sopimusten testaus - Validoidaan aina todellisia API-rajapintoja vastaan tuotantosopimuksia varten

Nyt kun tiedät, mihin se sopii, tutkitaan edistyneitä kykyjä.

Kehittyneet ominaisuudet

Nämä ominaisuudet ovat valinnaisia - pelkästään perusasioista voi saada valtavasti arvoa, mutta kun tarvitaan tuotannon realismia mittakaavassa, nämä työkalut ovat täällä.

Useita LLM-taustaosia

Oppaat: Useita LLM-taustaosia

# 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"

Hintojen rajoittaminen Simulointi

Oppaat: Nopeuden rajoittaminen ja lyöminen

Testaa, miten sovelluksesi käsittelee nopeusrajoja:

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

Virhesimulointi

# 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"

Tukee kaikkia 4xx- ja 5xx-koodeja.

Vaste välimuistiin

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

Seuraavat pyynnöt saavat pikaisia välimuistiin jätettyjä vastauksia.

Testiapuohjelmat: enimmäkseen lucid.mockllmapi.Testaaminen

Paketti: Enimmäkseen lucid.mockllmapi.Testaaminen

Kaikki edellä mainitut ominaisuudet ovat hyviä kehityksen kannalta, mutta entä automaattiset testaukset? Kumppanitestauspaketti tarjoaa sujuvan API:n, joka tekee integraatiotestistä tuuliajon - määritä valekäyttäytyminen vakuuttavasti ja anna HttpClient tee loput.

Asennus

dotnet add package mostlylucid.mockllmapi.Testing

Peruskäyttö

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[]>();

Useita päätepisteitä

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

Asetukset

Muotoasetukset:

// 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 = "" } }
})

Virhesimulaatio:

// Simple error
.WithError(404)

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

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

Virtaus:

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

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

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

Riippuvuusruiske

Kirjoitettu asiakas:

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

Nimetty asiakas:

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

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

Integraatiotestiesimerkki

[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);
}

Miten se toimii

Erytropoietiini MockLlmHttpHandler on a DelegatingHandler että:

  1. Estää lähteviä HTTP-pyyntöjä
  2. Vastaa pyyntöjä määritettyjä päätetapahtumia vastaan
  3. Ruiskuttaa valeasetukset kyselyparametrien ja HTTP-otsikoiden avulla
  4. Välittää muutetun pyynnön varsinaiselle pilkulle LLM API:lle

Näin voit käyttää todellista HttpClient Testeissäsi, kun hallitset helposti pilkullista API-käyttäytymistä muuttamatta sovelluskoodiasi.

Parhaita käytäntöjä ja vinkkejä

Työskenneltyään tämän työkalun kanssa useissa projekteissa, tässä ovat mallit, jotka toimivat parhaiten:

  1. Käytä aina kontekstia työnkulkuun - Varmistaa yhtenäiset tunnisteet ja tiedot monivaiheisissa operaatioissa
  2. Käyttömuoto tyyppiturvallisuuteen - Sovita se TypeScript-rajapintoihin
  3. Sekoita oikea ja valedata työkaluihin - Paras molemmista maailmoista
  4. Valitse oikea malli (ks. Ollaman malliopas täydelliset tiedot:
    • SUOSITETAAN MYÖNNETTÄVÄKSI: ministral-3:3b (3B paraamia, 32K konteksti) - JSONin tappaja! Ultranopea, erittäin tarkka, minimaalinen RAM
    • Tuotantoa muistuttava: llama3 8B paramit, 8K konteksti) - Paras laatu- ja suorituskykytasapaino
    • Korkealaatuinen: mistral-nemo (12B paramit, 128K konteksti) - Kompleksiset kuviot ja massiiviset aineistot
    • Resurssit ovat rajalliset: gemma3:4b tai phi3 - Kevyempi vaihtoehto

Täydellinen asiakirja-aineisto

Päätelmät

Frontendin kehitystyön ei tarvitse odottaa backend API:tä. mostlylucid.mockllmapi antaa sinulle:

  • Kontekstimuisti - Johdonmukainen ja edustava data monivaiheisten työnkulkujen kautta
  • Muotoilun hallinta - Tarkat skeemamääritelmät, jotka vastaavat tyyppejäsi
  • Yleispätevän protokollan tuki - REST, GraphQL, GRPC, SignalR, SSE, OpenAPI
  • Hybriditestaus - Sekoita todellista tuotantodataa tuotettuihin pilkkakuviin
  • Nollahuollot - Ei JSON-laitteita päivitettäväksi vaatimusten muuttuessa
  • Testauslaitokset - Fluent API integroitumiskokeisiin

Ero tämän ja perinteisen pilkkaamisen välillä? Eturintamasi toimii realistista, kontekstitietoista dataa vastaan alusta alkaen. Ei enää "se toimi valedatan kanssa, mutta epäonnistui todellisen datan kanssa" yllätyksiä.

Rakennatpa yksinkertaista blogia tai monimutkaista yrityssovellusta, iteroit nopeammin, testaat perusteellisemmin ja toimit luottavaisin mielin.

Oletko valmis aloittamaan?

docker compose up -d

Siinä kaikki, backendiä ei tarvita.

Finding related posts...
logo

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