Brainiary
A Rust REST API on Actix-web, with a Flutter client for Android and iOS.
The problem
Rust is a language you can read about indefinitely without actually learning it. The parts that matter — ownership across async boundaries, error propagation through layers, satisfying the borrow checker in a real request path — only surface once a project outgrows the tutorial stage.
Brainiary was a deliberate exercise in getting past that point. Rather than another toy CRUD example, the goal was a complete backend service with requirements that could not be hand-waved: durable persistence, credential storage that had to be correct rather than merely working, token-based sessions, and permissions that differed by role. Resume generation and management supplied a real domain to serve, with enough surface area to make the design decisions consequential.
What I built
A Rust REST API built with Actix-web 4, providing user authentication together with resume generation and management.
Authentication is JWT-based with bcrypt password hashing, backed by role-based access control for permissions. Data is persisted in PostgreSQL through the Diesel ORM, with the service running on the Tokio async runtime, Serde for JSON serialisation and Reqwest as the HTTP client. CORS is enabled for frontend integration and env_logger provides request and error logging.
A companion Flutter client consumes that API from a single Dart codebase targeting both Android and iOS. Having a real mobile consumer rather than a test script is why CORS handling and stateless token sessions were part of the design from the outset instead of being retrofitted — the client had to authenticate, hold a session and recover from expiry on its own.
Outcome
A working REST API covering registration, authentication and resume management, with JWT sessions, bcrypt-hashed credentials and role-based access control over PostgreSQL, plus a cross-platform Flutter client consuming it.
The value was in what the constraints forced. Diesel's compile-time query checking moves an entire class of database error out of runtime, in exchange for learning to satisfy it. Structuring handlers on Actix-web and Tokio made ownership across async boundaries concrete in a way that reading about it never had. Threading errors up from the database through the domain and out as HTTP responses pushed the design toward a single error type mapped explicitly to status codes, rather than the unwrapping that tutorial code tolerates.
Building both halves also meant the API had to be usable by something that was not the developer's own curl command — an API is only as good as the client work it makes easy.
Neither the service nor the client was released, which was the intended scope. The project was about the language and the design of the system, not about operating or shipping one.
Stack
Rust · Actix-web 4 · PostgreSQL · Diesel ORM · Tokio · JWT · bcrypt · Serde · Reqwest · Flutter · Dart