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 Task Executors ✅ 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.json
and.prettierrc
- Remove unnecessary dependencies, such as
@nx/js
, as we're working with a Rust project - Add a root
Cargo.toml
to 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 workspace layout 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 workspace layout 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
14
Now, 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
60
Update 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
14
Now, 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
17
Build 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