<?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: Haowang</title>
    <description>The latest articles on DEV Community by Haowang (@haowang604).</description>
    <link>https://dev.to/haowang604</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1769139%2F8314938d-705c-45cd-9020-46365bc150eb.png</url>
      <title>DEV Community: Haowang</title>
      <link>https://dev.to/haowang604</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/haowang604"/>
    <language>en</language>
    <item>
      <title>I built a blazing-fast OpenAPI mock server in Rust — starts in milliseconds, zero config, dynamic fake data</title>
      <dc:creator>Haowang</dc:creator>
      <pubDate>Wed, 15 Jul 2026 03:36:46 +0000</pubDate>
      <link>https://dev.to/haowang604/i-built-a-blazing-fast-openapi-mock-server-in-rust-starts-in-milliseconds-zero-config-dynamic-jmd</link>
      <guid>https://dev.to/haowang604/i-built-a-blazing-fast-openapi-mock-server-in-rust-starts-in-milliseconds-zero-config-dynamic-jmd</guid>
      <description>&lt;p&gt;Hey HN,&lt;/p&gt;

&lt;p&gt;Most OpenAPI mock servers I've worked with fall into one of three buckets: they're slow to boot (JVM warmup, Node module resolution), they need Docker just to run, or they return the same hardcoded stub on every request. None of that is great when you just want to unblock frontend work or sketch out an integration against a spec that's still moving.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;mock-cli&lt;/strong&gt; — a single static binary written in Rust that reads any OpenAPI 3 spec (YAML or JSON) and serves &lt;strong&gt;schema-aware, dynamic&lt;/strong&gt; fake data over HTTP. No runtime, no container, no config file.&lt;/p&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/wanghao12345/mock-cli" rel="noopener noreferrer"&gt;https://github.com/wanghao12345/mock-cli&lt;/a&gt;&lt;br&gt;
npm: &lt;code&gt;npm install -g @mock-cli/server&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What makes it different
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Native Rust binary.&lt;/strong&gt; Cold start is in the low milliseconds. No JVM, no Node overhead, no Docker pull. You run it, it serves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic, schema-compliant data — not static stubs.&lt;/strong&gt; Every request produces different fake data that still honors your schema: &lt;code&gt;format: email&lt;/code&gt; gives you a realistic email, &lt;code&gt;format: uuid&lt;/code&gt; gives you a v4 UUID, &lt;code&gt;enum&lt;/code&gt; picks a valid value, &lt;code&gt;required&lt;/code&gt; fields are always present, &lt;code&gt;minItems&lt;/code&gt;/&lt;code&gt;maxItems&lt;/code&gt; are respected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path-aware.&lt;/strong&gt; If your route is &lt;code&gt;/pets/{petId}&lt;/code&gt; and the response schema has a &lt;code&gt;petId&lt;/code&gt; field, the value from the URL is injected into the response (coerced to the schema type). So &lt;code&gt;GET /pets/123&lt;/code&gt; returns &lt;code&gt;{"petId": 123, ...}&lt;/code&gt; — consistent with the request context, not random noise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cycle-safe &lt;code&gt;$ref&lt;/code&gt; resolution.&lt;/strong&gt; Recursive schemas are bounded so the server never blows the stack on a self-referencing model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correct status codes out of the box.&lt;/strong&gt; &lt;code&gt;200&lt;/code&gt; on success, &lt;code&gt;404&lt;/code&gt; for unknown paths, &lt;code&gt;405&lt;/code&gt; for unsupported methods, &lt;code&gt;501&lt;/code&gt; when there's no &lt;code&gt;200&lt;/code&gt; response defined. Your client's error handling actually gets exercised.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;All HTTP methods wired up.&lt;/strong&gt; GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD, TRACE.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Single binary, cross-platform.&lt;/strong&gt; macOS / Linux / Windows, x64 and arm64. Install via npm (auto-picks the right prebuilt binary) or grab the binary from GitHub Releases. Works offline.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  30-second demo
&lt;/h2&gt;

&lt;p&gt;Drop a spec:&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;openapi&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;3.0.3&lt;/span&gt;
&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Petstore&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1.0.0&lt;/span&gt;
&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="s"&gt;/pets/{petId}&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;parameters&lt;/span&gt;&lt;span class="pi"&gt;:&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="s"&gt;petId&lt;/span&gt;
          &lt;span class="na"&gt;in&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;path&lt;/span&gt;
          &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;schema&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;integer&lt;/span&gt;
      &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;200'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OK&lt;/span&gt;
          &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;application/json&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;schema&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;petId&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;integer&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;vaccinated&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;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mock-cli swagger.yaml
&lt;span class="c"&gt;# ✓ Loaded "swagger.yaml" (1 paths)&lt;/span&gt;
&lt;span class="c"&gt;# ✓ Listening on 127.0.0.1:3333&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hit it:&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:3333/pets/123
&lt;span class="c"&gt;# {"petId":123,"name":"Dr. Margret Kihn","vaccinated":true}&lt;/span&gt;

curl http://localhost:3333/pets/456
&lt;span class="c"&gt;# {"petId":456,"name":"Sarah Connor","vaccinated":false}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice &lt;code&gt;petId&lt;/code&gt; echoes the path param, but &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;vaccinated&lt;/code&gt; are fresh fake data on every call. That's the whole point — your frontend gets a realistic, varying response shape without you hand-writing fixtures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# npm (recommended — picks the right prebuilt binary for your platform)&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @mock-cli/server

&lt;span class="c"&gt;# or build from source&lt;/span&gt;
cargo &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--path&lt;/span&gt; crates/cli

&lt;span class="c"&gt;# or just run it without installing&lt;/span&gt;
cargo run &lt;span class="nt"&gt;--release&lt;/span&gt; &lt;span class="nt"&gt;--&lt;/span&gt; examples/swagger.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Rust?
&lt;/h2&gt;

&lt;p&gt;Honestly, because I wanted a tool I could ship as one static binary with no runtime dependency, and because the OpenAPI spec is a big tagged-union-shaped data model that maps cleanly onto Rust enums. The parsing and generation core (&lt;code&gt;crates/core&lt;/code&gt;) has no IO — it's pure data transformation — which makes it trivial to test and reuse. The HTTP layer (&lt;code&gt;crates/server&lt;/code&gt;) is axum, and the CLI (&lt;code&gt;crates/cli&lt;/code&gt;) is clap. Clean three-crate split.&lt;/p&gt;

&lt;h2&gt;
  
  
  Roadmap
&lt;/h2&gt;

&lt;p&gt;Done: dynamic mocking, path param injection, schema &lt;code&gt;format&lt;/code&gt;/&lt;code&gt;enum&lt;/code&gt;/&lt;code&gt;required&lt;/code&gt;/array bounds, &lt;code&gt;$ref&lt;/code&gt; resolution with cycle safety, correct HTTP status codes, configurable bind host, graceful shutdown.&lt;/p&gt;

&lt;p&gt;Planned: hot reload on spec change, request validation against the spec, custom faker rules via config, multi-spec composition.&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;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @mock-cli/server
mock-cli examples/swagger.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Repo + full docs: &lt;a href="https://github.com/wanghao12345/mock-cli" rel="noopener noreferrer"&gt;https://github.com/wanghao12345/mock-cli&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Happy to hear feedback — especially on the faker behavior (what formats/enums you'd like better coverage for) and whether hot-reload or request validation should land first. Issue threads are open.&lt;/p&gt;

&lt;p&gt;MIT licensed. Written in Rust 1.85+.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>automation</category>
      <category>devops</category>
    </item>
    <item>
      <title>Telegram Mini Apps Journey</title>
      <dc:creator>Haowang</dc:creator>
      <pubDate>Sat, 24 Aug 2024 10:28:36 +0000</pubDate>
      <link>https://dev.to/haowang604/telegram-mini-apps-journey-28gj</link>
      <guid>https://dev.to/haowang604/telegram-mini-apps-journey-28gj</guid>
      <description>&lt;p&gt;I have recently developed several Telegram mini apps, and today I would like to share my development experience.&lt;/p&gt;

&lt;p&gt;If you want to develop a Telegram mini app, you need to possess the following skills：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You need to have some development experience in front-end and back-end technology, which is the most basic. If you don't have this experience, then you won't be able to develop a Telegram Mini app on your own.&lt;br&gt;
The main technologies used include &lt;strong&gt;React&lt;/strong&gt;, &lt;strong&gt;NextJS&lt;/strong&gt;, &lt;strong&gt;Node.js&lt;/strong&gt;, &lt;strong&gt;MySQL&lt;/strong&gt;, &lt;strong&gt;MongoDB&lt;/strong&gt;, etc&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You need to understand wallet operations and Ton smart contract development, as they are required for coin issuance and other operations.&lt;br&gt;
The main technologies used are: &lt;strong&gt;Func&lt;/strong&gt;, &lt;strong&gt;Tact&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you have the basic skills above, then you can develop a Telegram Mini app.But this is still far from true commercialization, because the soul of a product lies in its design and operation, and technology is only the most fundamental aspect of the product.&lt;/p&gt;

&lt;p&gt;This link contains some of my recently developed products, including the Telegram Mini app &lt;a href="https://hwangcn-portfolio.vercel.app/" rel="noopener noreferrer"&gt;https://hwangcn-portfolio.vercel.app/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Welcome to leave messages for discussion and exchange of technical products &lt;a href="https://hwangcn-portfolio.vercel.app/" rel="noopener noreferrer"&gt;https://hwangcn-portfolio.vercel.app/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>telegram</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
