DEV Community

Luís Fernando Vendrame
Luís Fernando Vendrame

Posted on

Building a File-Based Mock Server in Rust: A Learning Journey

Every developer has a folder of "side projects." Some are ambitious, world-changing ideas, while others are born from a simple, immediate need. My latest project, rs-mock-server, falls firmly into the second category. I needed a simple mock server for another project, one that didn't require complex configuration files or a steep learning curve. I also wanted to sharpen my Rust skills. Why not kill two birds with one stone?

This journey turned out to be more than just building a tool; it was a deep dive into the heart of Rust's most powerful (and sometimes feared) features.

The Problem: Simple Mocks, No Fuss

For front-end development or testing microservices, you often need a fake API that returns predictable data. I wanted a server that worked directly from the file system. If I need a /users/1 endpoint, I should just have to create a /users/1 file. The folder structure itself should be the API contract.

This idea became the core concept for rs-mock-server: a zero-configuration mock server that maps directories and files directly to API routes.

The Learning Curve: More Than Just a Project

Building this server was the perfect excuse to get my hands dirty and truly grapple with Rust's core concepts. I'll be the first to admit it's a first version with plenty of "horrible" code, but that's a natural part of the learning process! The initial goal was to make it work; now, the journey of improving and refactoring it begins.

🤝 Befriending the Borrow Checker

Ah, the infamous Borrow Checker. Like many, my initial experience with it felt like wrestling with a stubborn compiler. But this project forced me to move beyond just making the errors disappear. I started to think in terms of ownership, lifetimes, and borrowing. Instead of passing values around and hoping for the best, I began to design how data flowed through the application. It was a mindset shift from "fighting the compiler" to "working with the language," and it was gratifying.

🌐 Web Services with Axum

On top of Tokio, I used Axum, a modern and ergonomic web framework. Axum’s extractor pattern is brilliant. It makes pulling data from requests—whether it's a path parameter, a query, or a header—spotless and boilerplate-free. Building the routing logic, which dynamically maps file paths like get{id}.json to routes like /api/users/:id, was a fascinating challenge that Axum made manageable.

The Result: rs-mock-server

After navigating these challenges, rs-mock-server was born. It's a lightweight, fast, and incredibly simple tool that does exactly what I set out to create.

  • A folder at ./mocks/api/users becomes the /api/users route.
  • A file named get.json inside it responds to GET /api/users.
  • A file named get{id}.json handles dynamic requests like GET /api/users/123.

It was the perfect project—small enough to finish, but complex enough to teach me valuable lessons.

From Private Tool to Public Crate

Beyond the code itself, a huge desire of mine was to learn the full lifecycle of a public project. It's one thing to build a tool for yourself, but it's another to package and publish it so everyone can use it easily.

Figuring out how to document the project, configure the Cargo.toml metadata, and publish it to crates.io was the final, crucial step. Seeing my project available to anyone with a simple cargo install command was an incredibly rewarding conclusion to this learning journey.

Try It Out!

This journey was a powerful reminder that the best way to learn is by building. I not only solved a practical problem but also came away with a much deeper understanding of the Rust ecosystem.

If you have a similar need or are just curious, I’d love for you to check it out.

Of course, I'm not so good with words, so I used some LLM to improve this text, but it kept the soul.

Top comments (0)