<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emmanuel King Kasulani</title>
    <description>The latest articles on DEV Community by Emmanuel King Kasulani (@kasulani).</description>
    <link>https://dev.to/kasulani</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3887368%2F12fb0009-a2ee-4ed2-9041-04265b61d9fc.jpg</url>
      <title>DEV Community: Emmanuel King Kasulani</title>
      <link>https://dev.to/kasulani</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kasulani"/>
    <language>en</language>
    <item>
      <title>Your Spec Already Has Mock Data</title>
      <dc:creator>Emmanuel King Kasulani</dc:creator>
      <pubDate>Sun, 19 Apr 2026 17:44:51 +0000</pubDate>
      <link>https://dev.to/kasulani/your-spec-already-has-mock-data-4lp1</link>
      <guid>https://dev.to/kasulani/your-spec-already-has-mock-data-4lp1</guid>
      <description>&lt;p&gt;Every new project starts the same way. The API contract is agreed, the spec is written, and now the frontend team needs something to build against. They shouldn't have to set up mock servers with config files just to start working. So I do what every backend engineer does — I scaffold the service, wire up every endpoint with hardcoded JSON responses, deploy it to staging, and tell the frontend team to point their app at it.&lt;/p&gt;

&lt;p&gt;It works. Frontend builds against staging. Responses are predictable, the contract is fresh, and nobody had to configure anything. The dummy endpoints are throwaway code — I would have preferred to jump straight into real implementation after designing the spec — but it's a small tax to unblock the team.&lt;/p&gt;

&lt;p&gt;Then the real implementation starts replacing the dummy endpoints. One by one, hardcoded responses become live database queries. And this is where things unravel.&lt;/p&gt;

&lt;p&gt;The responses that were deterministic — &lt;code&gt;{"name": "Fido"}&lt;/code&gt; every single time — now depend on database state, test data, and the order of previous requests. Frontend's assertions break. Their UI tests become flaky. The predictable surface they were building against quietly disappears underneath them.&lt;/p&gt;

&lt;p&gt;So they do what they avoided at the start: they set up their own mock server. WireMock stub mappings. Prism config. Postman saved responses. Config files that describe the API in a parallel artifact, separate from the spec.&lt;/p&gt;

&lt;p&gt;By this point, the spec has evolved through several sprints. The mock configs are stale on day one. And now drift begins — two descriptions of the same API that silently disagree, with nobody maintaining the sync.&lt;/p&gt;

&lt;p&gt;One problem created the other. The scaffold was a workaround to avoid config-heavy mocks. But it was temporary by design. When it dissolved, the config-heavy mocks became inevitable — and by then, the spec had moved far enough that the configs were already wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The root cause
&lt;/h2&gt;

&lt;p&gt;After hitting this cycle enough times, I noticed the common thread: every approach we tried kept mock data somewhere other than the spec.&lt;/p&gt;

&lt;p&gt;Hardcoded responses lived in scaffold code. Stub mappings lived in config files. Saved responses lived in Postman collections. Each was a parallel artifact duplicating information already in the OpenAPI spec — schemas, status codes, example values — and each drifted from it the moment the API evolved.&lt;/p&gt;

&lt;p&gt;The gap between the spec and the mock grows with every sprint. It doesn't matter which tool you pick. If the mock data lives in a separate artifact, the question isn't whether it'll disagree with the spec. It's when.&lt;/p&gt;

&lt;h2&gt;
  
  
  The insight hiding in plain sight
&lt;/h2&gt;

&lt;p&gt;OpenAPI has supported &lt;code&gt;example&lt;/code&gt; values on properties since version 3.0. Most specs already use them — for documentation rendering, for code generation, for Swagger UI. These aren't decorative. They're structured, schema-adjacent data authored by backend engineers who design the API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;schemas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Pet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;object&lt;/span&gt;
      &lt;span class="na"&gt;properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;example&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Fido"&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;enum&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;available&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pending&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;adopted&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
        &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;string&lt;/span&gt;
          &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;email&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That fragment contains three mock values: an authored example (&lt;code&gt;"Fido"&lt;/code&gt;), a constrained set (&lt;code&gt;available&lt;/code&gt;, &lt;code&gt;pending&lt;/code&gt;, &lt;code&gt;adopted&lt;/code&gt;), and a format hint (&lt;code&gt;email&lt;/code&gt;). Combined with the schema's types, constraints, and structure, the spec has everything a mock server needs to produce realistic responses.&lt;/p&gt;

&lt;p&gt;Yet every mock tool ignores this and asks you to define mock data somewhere else.&lt;/p&gt;

&lt;h2&gt;
  
  
  So I built a tool that doesn't
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://mimikos.dev/getting-started" rel="noopener noreferrer"&gt;Mimikos&lt;/a&gt; to treat the OpenAPI spec as the only input. No config files. No scaffold services. No separate mock data to maintain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mimikos start petshop.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;🎭 mimikos 0.3.9
Spec: PetShop Pro (OpenAPI 3.0.3)
Operations: 27 endpoints classified

  METHOD  PATH                                  BEHAVIOR   CONFIDENCE
  GET     /pets                                 → list        high
  POST    /pets                                 → create      high
  GET     /pets/{petId}                         → fetch       high
  PATCH   /pets/{petId}                         → update      high
  DELETE  /pets/{petId}                         → delete      high
  GET     /store/orders                         → list        high
  GET     /clinics/{clinicId}/rooms             → list        high
  GET     /me                                   → fetch       high
  ...

Listening on :8080 (deterministic mode, strict=false)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It reads the spec, classifies every endpoint automatically, and serves responses generated from the schemas. Authored &lt;code&gt;example&lt;/code&gt; values are used directly. Fields named &lt;code&gt;email&lt;/code&gt; get email addresses. Fields with &lt;code&gt;format: date-time&lt;/code&gt; get timestamps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/pets/42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"d1b2f3a4-5678-9abc-def0-1234567890ab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Fido"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"available"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alice.johnson@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2024-08-15T10:30:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;"Fido"&lt;/code&gt; comes from the spec's example. &lt;code&gt;"available"&lt;/code&gt; from the enum. The UUID, email, and timestamp are generated from format and field-name awareness. No configuration step between "I have a spec" and "I have a working mock."&lt;/p&gt;

&lt;p&gt;And crucially: the same request always returns the same response. Deterministic by default — the property that staging lost the moment real implementations replaced the dummy endpoints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it doesn't drift
&lt;/h2&gt;

&lt;p&gt;One input means nothing to sync. When the spec changes, responses change. There's no parallel artifact to update.&lt;/p&gt;

&lt;p&gt;Two design choices keep it stable over time:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-field sub-seeding&lt;/strong&gt; — adding or removing a field in the schema doesn't change existing field values. Only the affected field changes. Schema evolution doesn't cascade into unrelated snapshot failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spec examples take priority&lt;/strong&gt; — if you authored an &lt;code&gt;example&lt;/code&gt; value, Mimikos uses it. It only generates data for fields that don't have explicit values. You control exactly how much is authored vs. generated.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it won't do
&lt;/h2&gt;

&lt;p&gt;Mimikos mocks the API contract, not business logic. It won't simulate authentication, enforce rate limits, or replicate stateful workflows in deterministic mode. These are deliberate boundaries — a mock that replicates business logic is just another implementation that drifts in more dangerous ways.&lt;/p&gt;

&lt;p&gt;For CRUD testing, there's a stateful mode (&lt;code&gt;--mode stateful&lt;/code&gt;) where POST creates resources and GET retrieves them. But the default is pure deterministic generation — same request in, same response out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;install &lt;/span&gt;github.com/mimikos-io/mimikos/cmd/mimikos@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or download a pre-built binary from &lt;a href="https://github.com/mimikos-io/mimikos/releases" rel="noopener noreferrer"&gt;GitHub Releases&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Grab the demo spec to explore the full feature set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-o&lt;/span&gt; petshop.yaml https://raw.githubusercontent.com/mimikos-io/mimikos/main/testdata/specs/petshop.yaml
mimikos start petshop.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Documentation: &lt;a href="https://mimikos.dev/getting-started" rel="noopener noreferrer"&gt;mimikos.dev&lt;/a&gt;&lt;br&gt;
Source: &lt;a href="https://github.com/mimikos-io/mimikos" rel="noopener noreferrer"&gt;github.com/mimikos-io/mimikos&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Your spec already has mock data. You just need something that uses it.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>openapi</category>
      <category>testing</category>
      <category>mocking</category>
    </item>
  </channel>
</rss>
