City info is a RESTful application that takes handles requests on /{city_name}
and responds with "useful" data for that city_name
The main motivation for this toy program is to introduce the reader to a few key concepts through the lens of a "production" application:
- async rust leveraging tokio and Futures
- Most importantly, the Actor/Handle model described by Alice Rhyl in this fantastic presentation
- other common crates leveraged in production rust code, including (but not limited to)
This simple application is broken into a handful of independent tasks:
- An axum router which serves REST API requests/responses. It sends requests via a
tokio::sync::mpsc
to... - The dispatcher task, which starts a number of "data fetcher" tasks, fans out requests to them, and aggregates their responses into one response to send back to the axum router
- One or more "data fetcher" tasks which handle requests and respond with interesting data
This directory is set up as a cargo workspace. There is a bin directory which contains the files required to create a running binary for our program, and a lib directory which contains the "business logic" of our application broken into smaller "crates". This is done to facilitate testing (which is definitely overkill for this specific application, but representative of how a production repo might be laid out)
As usual, some work is left for the reader. For those who want to skip ahead, a solution can be found on the solutions
branch
The reader should:
- ensure all tests pass by addressing any
// TODO
comments
The reader may:
- Make the following implementation more async-friendly by addressing the "exercises left for the reader" in city_info/bin/main.rs and/or city_info/lib/dispatcher/lib.rs. With these changes implemented the application should easily be able to generate more than enough concurrent requests to be rate-limited by the public APIs it leverages (but please don't do this!)
Ensure you have cargo and all the various rust compilation tools installed (see rustup.rs). Then, to build the source files, run the following command in this directory:
cargo build
To run all associated unit and module/crate tests (and build again if you've made changes)
cargo test
If you wish to run tests faster, with a fancier output, see cargo-nextest.
** NOTE: You will see that some unit tests are failing on the master branch, that's the exercise! **
To run the application simply do
cargo run
You can then make requests to the running server:
$ curl -k http://127.0.0.1:4242/Chicago
$ curl -k http://127.0.0.1:4242/San%20Jose