Add a New Rust Project
The code for this example is available on GitHub:
Example repository/nrwl/nx-recipes/tree/main/rust
Supported Features
We'll be using an Nx Plugin for Rust called @monodon/rust.
โ Run Tasks โ Cache Task Results โ Share Your Cache โ Explore the Graph โ Distribute Task Execution โ Integrate with Editors โ Automate Updating Nx โ Enforce Module Boundaries โ Use Code Generators โ Automate Updating Framework Dependencies
Create the workspace with the @monodon/rust preset
We'll use the preset created by the @monodon/rust plugin to create the workspace with everything we need to build Rust applications.
โฏ
npx -y create-nx-workspace@latest acme --preset=@monodon/rust
Using the preset provided by @monodon/rust will:
- Remove any unnecessary configuration files for working with Rust projects, such as tsconfig.jsonand.prettierrc
- Remove unnecessary dependencies, such as @nx/js, as we're working with a Rust project
- Add a root Cargo.tomlto manage workspace members
Create the application
Let's generate a new application using @monodon/rust.
The command below uses the as-provided directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the derived option, omit the --directory flag. See the as-provided vs. derived documentation for more details.
โฏ
nx g @monodon/rust:binary myapp --directory=apps/myapp
Create a library
Let's generate a new library using @monodon/rust.
The command below uses the as-provided directory flag behavior, which is the default in Nx 16.8.0. If you're on an earlier version of Nx or using the derived option, omit the --directory flag. See the as-provided vs. derived documentation for more details.
โฏ
nx g @monodon/rust:library cats --directory=libs/cats
Update the cats library
First, let's update the Cargo.toml file to define the dependencies for the library.
1[package]
2name = "cats"
3version = "0.1.0"
4edition = "2021"
5
6[dependencies]
7actix-web = "4"
8
9[dependencies.serde]
10version = "1"
11features = ["derive"]
12
13# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
14Now, let's add the code to handle the cats route.
1use std::collections::HashSet;
2use std::sync::Mutex;
3
4use actix_web::web::*;
5use actix_web::{get, post, HttpResponse, Responder, Scope};
6
7pub struct Cats {
8    cats: Mutex<HashSet<Cat>>,
9}
10
11
12struct Cat {
13    name: String,
14    age: u8,
15}
16
17
18async fn get_cats(data: Data<Cats>) -> impl Responder {
19    let cats = data.cats.lock().unwrap();
20
21    println!("Cats {:?}", &cats);
22
23    Json(cats.clone())
24}
25
26
27async fn add_cat(cat: Json<Cat>, data: Data<Cats>) -> impl Responder {
28    let mut cats = data.cats.lock().unwrap();
29
30    println!("Adding {:?}", &cat);
31
32    cats.insert(cat.into_inner());
33
34    HttpResponse::Ok()
35}
36
37pub fn create_cat_data() -> Data<Cats> {
38    Data::new(Cats {
39        cats: Mutex::new(HashSet::new()),
40    })
41}
42
43pub fn create_cat_scope(data: &Data<Cats>) -> Scope {
44    scope("/cats")
45        // Cloning is cheap here because internally, Data uses `Arc`
46        .app_data(Data::clone(data))
47        .service(add_cat)
48        .service(get_cats)
49}
50
51
52mod tests {
53    
54    fn it_works() {
55        let result = 2 + 2;
56        assert_eq!(result, 4);
57    }
58}
59
60Update the application
Let's create the http-server application and use the library to add the cats route.
First, we need to update the Cargo.toml file to define the application's dependencies.
1[package]
2name = "myapp"
3version = "0.1.0"
4edition = "2021"
5
6
7[dependencies]
8actix-web = "4"
9cats = { path = "../../libs/cats" }
10
11
12# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
13
14Now, let's update the application's code itself.
1use actix_web::{App, HttpServer};
2
3use cats::{create_cat_data, create_cat_scope};
4
5
6async fn main() -> std::io::Result<()> {
7    // HttpServer:new creates multiple threads to handle requests.
8    // We need to make sure that the shared cat data is created once before the HttpServer
9    // We can then pass this reference to the create_cat_scope so that all threads have access to the same data
10    let cat_data = create_cat_data();
11    HttpServer::new(move || App::new().service(create_cat_scope(&cat_data)))
12        .bind(("127.0.0.1", 8080))?
13        .run()
14        .await
15}
16
17Build and Run the Application
To run the application, run the following command and then navigate your browser to http://localhost:8080/cats
โฏ
nx run myapp:run
To build the application, run the following command:
โฏ
nx build myapp