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

Eight crates do all of the work — the toolbox table further down this page is also the complete dependency list, and lesson 12 holds it up against the original’s Maven tree. Every one gets introduced properly in the lesson where it first earns its place.

What’s inside

  1. The app you already know: a tour of JPetStore 6 and the port plan
  2. Project skeleton: Axum, an error strategy, and the first route
  3. The database: schema, migrations, and seed data with SQLx
  4. Modeling the catalog: types that make bad states impossible
  5. Catalog pages: Askama templates and handlers
  6. Search
  7. The cart: sessions without a session bean
  8. Accounts: signup, sign-in, and password hashing
  9. Checkout: the shipping and billing forms, and the card-number lesson
  10. Placing the order: one transaction for order, line items, and inventory
  11. Order history and the account page: feature parity
  12. 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.

None of the background under “Before you start” below is a hard requirement, but each piece you bring makes the course move faster.

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.