If you wrote Java for a living any time in the last twenty years, you’ve met JPetStore. It’s the canonical layered web app: Stripes actions on top, Spring wiring in the middle, MyBatis SQL mappers underneath, a WAR file on Tomcat at the end. A whole generation of us learned “enterprise architecture” from that little pet store.
This course takes the exact app you already know and rebuilds it in Rust,
layer by layer, until the whole thing is one binary you start with
cargo run. No app server. No container-managed anything. Same features,
same database schema, a fraction of the moving parts.
What you’ll build
A feature-parity port of JPetStore 6: browsable catalog (fish, dogs, cats, reptiles, birds), search, a session-backed cart, account signup and sign-in, checkout, and order history. Server-rendered HTML the way the original did it, just without the JSP.
Every lesson ends with a running app. The companion repo, jpetstore-rs, gets a git tag per lesson, so you can diff any checkpoint against your own work.
Every layer you know, replaced
| JPetStore 6 | The port | The trade |
|---|---|---|
| Stripes ActionBeans + JSP | Axum handlers + Askama templates | Templates type-checked at compile time |
| MyBatis SQL mappers | SQLx | Still SQL-first, but the queries are checked before the app runs |
Spring DI + @Transactional |
Plain traits + explicit transactions | The wiring is code you can read |
| HSQLDB in-memory | SQLite | Same zero-install dev experience |
| WAR on Tomcat | One static binary | This is the punchline |
The toolbox
Eight crates do all of the work. Each is linked to its own documentation if you want to read ahead, but every one gets introduced properly in the lesson where it first earns its place:
| Crate | Job in the port | First appears |
|---|---|---|
| axum | Routing and handlers: the Stripes replacement | Lesson 1 |
| tokio | The async runtime everything runs on | Lesson 1 |
| thiserror | Derives the boilerplate on the app’s one error enum | Lesson 2 |
| askama | HTML templates checked at compile time: the JSP replacement | Lesson 2 |
| sqlx | SQL with compile-time checked queries: the MyBatis replacement | Lesson 3 |
| serde | Turns form and query strings into typed structs | Lesson 6 |
| tower-sessions | The session the cart lives in | Lesson 7 |
| argon2 | Password hashing, where the original stored plaintext | Lesson 8 |
That table is also the complete dependency list. Lesson 12 holds it up against the original’s Maven tree.
What’s inside
- The app you already know: a tour of JPetStore 6 and the port plan
- Project skeleton: Axum, an error strategy, and the first route
- The database: schema, migrations, and seed data with SQLx
- Modeling the catalog: types that make bad states impossible
- Catalog pages: Askama templates and handlers
- Search
- The cart: sessions without a session bean
- Accounts: signup, sign-in, and password hashing
- Checkout: the shipping and billing forms, and the card-number lesson
- Placing the order: one transaction for order, line items, and inventory
- Order history and the account page: feature parity
- Testing the port, and the final scorecard
Every lesson closes with one optional challenge if you want to go further than the walkthrough.
Who this is for
You’ve shipped code in Java, C#, or another typed language, and you’re Rust-curious. You don’t need prior Rust; we learn it by porting, and where a concept deserves more depth than a lesson can give it, I’ll point you at the right chapter of the book instead of pretending a paragraph covers it. What this is not is a from-zero syntax course. If you’ve never read code at all, start elsewhere and come back.
Before you start
Three kinds of background help. None are hard requirements, but each one you bring makes the course move faster:
Some Rust. The course teaches Rust by porting, but it moves quicker if the syntax isn’t brand new. The Rust Book chapters 1 through 9 cover everything lessons 1 and 2 assume you can absorb on the fly: ownership, structs and enums, and error handling. If you learn better by doing, Rustlings is the same ground as small exercises.
The Java side of the comparison. Every lesson explains what the original does before replacing it, so you can follow along cold. Still, the comparisons land harder if Spring Framework, Spring Boot, and MyBatis ring bells rather than alarm bells. The original’s front end is Stripes, a framework that has been dormant for years, which is itself part of the story: the app outlived its framework, and the data layer is what kept it portable.
The app itself. Skim the jpetstore-6 repo before lesson 1 if you like, or just wait: the first lesson is a guided tour, original running in Docker included.
How to take this course
You build the port in your own repo, starting from cargo new in lesson 1.
The companion repo is the
answer key, not the workbook.
Each lesson works the same way. The prose explains the idea against the Java equivalent you already know, and shows every new pattern once, in full — you’ll type that code understanding each line. Then a Build it table at the end lists every file the lesson touches, and most of the work it assigns is applying the pattern you just saw to the cases the lesson didn’t show: the lesson writes one id newtype, you write the other two. That repetition is where the learning actually happens, so don’t skip it by pasting.
The table marks each file write (apply the pattern), copy (transcription
with nothing to teach — CSS, ported SQL — take it from the answer key
guilt-free), modify (small edits to existing files), or generated (tool
output). Done when gives you an objective check, usually a test count or a
curl output. And the answer key link shows the complete change as a diff —
open it after your check passes to compare approaches, or when you’re
genuinely stuck, not before you’ve tried. If you diverge too far, any
lesson’s tag is a clean reset point.
After the port
The free course is complete on its own; you end with the full app running locally. Paid follow-ups will pick up where it stops: deploying the binary (and why there’s no app server to deploy), then splitting the app into an API with a client-side UI across the CSR, SSR, and SSG spectrum.
JPetStore 6 is Apache-2.0 licensed by the MyBatis team. This port and course build on their work, with attribution and gratitude.
