Write an HTTP API in Rust through a series of test-driven exercises.
The tasks include:
- Call an external HTTP API to retrieve data asynchronously by using reqwest.
- Build an HTTP API by using axum.
- Handle errors by using thiserror and anyhow.
- Write tests by mocking external APIs with wiremock.
- Use tracing for logs and traces. You will visualize traces by running jaeger locally.
A simple HTTP API that checks if Yoda is taller than a given Star Wars character.
For example, if you want to check if Yoda is taller than Luke Skywalker,
you can do this GET request with curl
:
$ curl 127.0.0.1:3000/taller/luke
{
"query": "luke",
"person": "Luke Skywalker",
"taller": false
}
This is the architecture of the system:
graph TD;
C(HTTP Client)-->S(HTTP Server);
S-->Swapi;
- HTTP Client: the software you can use to interact with your API. It can be anything:
curl
, Insomnia, and so on. - HTTP Server: the component you will implement.
- Swapi: the service you are going to use to retrieve info about Star Wars characters.
This is the flow of the system:
sequenceDiagram
participant C as HTTP Client
participant S as HTTP Server
participant Swapi
C->>S: Is Yoda taller than Luke?
S->>Swapi: How tall is Luke?
Swapi->>S: Luke is *this* tall
S->>S: Compare Luke vs Yoda height
S->>C: Yoda is not taller than Luke
Let's translate some high-level details from the previous diagram:
sequenceDiagram
participant C as HTTP Client
participant S as HTTP Server
participant Swapi
C->>S: GET /taller/luke
S->>Swapi: Give me info about Luke
Swapi->>S: Luke info in JSON
S->>S: Compare Luke vs Yoda height
S->>C: {"query":"luke", person":"Luke Skywalker", "taller":false}
# Clone this repo
git clone https://github.com/MarcoIeni/rust-api-workshop
cd rust-api-workshop
# Create your branch
git checkout -b workshop
# Run the tests to make sure your rust installation works
cargo test
Open the rust-api-workshop
project in your favorite editor.
By looking at the main Cargo.toml
, you can see there are two crates:
workshop
: the crate you will use to implement the HTTP API.yoda-taller
: the crate that contains a possible implementation of the HTTP API. Please, don't look inside this folder before trying to solve the exercises by yourself, first.
To start the workshop, open the file src/workshop/tests/api/main.rs
.
After you finished the workshop, take a look at the final solution
(src/yoda-taller
), run it and see the traces it produces in jaeger:
# start jaeger (and auto remove on stop)
docker run --name jaeger --rm -d -p6831:6831/udp -p6832:6832/udp -p16686:16686 jaegertracing/all-in-one:latest
# check if it's running
docker ps
# open the web ui
open http://localhost:16686/
cargo run -p yoda-taller
curl http://localhost:3000/taller/luke
In the following, you find the recordings of people going through the workshop. If you want to add yours, open a PR!
Some pieces of code, names or conventions are inspired by: