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
.
❯
nx g @monodon/rust:binary myapp
Create a library
Let's generate a new library using @monodon/rust
.
❯
nx g @monodon/rust:library cats
Update the cats
library
First, let's update the Cargo.toml
file to define the dependencies for the library.
[package]
name = "cats"
version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = "4"
[dependencies.serde]
version = "1"
features = ["derive"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Now, let's add the code to handle the cats
route.
use std::collections::HashSet;
use std::sync::Mutex;
use actix_web::web::*;
use actix_web::{get, post, HttpResponse, Responder, Scope};
pub struct Cats {
cats: Mutex<HashSet<Cat>>,
}
struct Cat {
name: String,
age: u8,
}
async fn get_cats(data: Data<Cats>) -> impl Responder {
let cats = data.cats.lock().unwrap();
println!("Cats {:?}", &cats);
Json(cats.clone())
}
async fn add_cat(cat: Json<Cat>, data: Data<Cats>) -> impl Responder {
let mut cats = data.cats.lock().unwrap();
println!("Adding {:?}", &cat);
cats.insert(cat.into_inner());
HttpResponse::Ok()
}
pub fn create_cat_data() -> Data<Cats> {
Data::new(Cats {
cats: Mutex::new(HashSet::new()),
})
}
pub fn create_cat_scope(data: &Data<Cats>) -> Scope {
scope("/cats")
// Cloning is cheap here because internally, Data uses `Arc`
.app_data(Data::clone(data))
.service(add_cat)
.service(get_cats)
}
mod tests {
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
}
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.
[package]
name = "myapp"
version = "0.1.0"
edition = "2021"
[dependencies]
actix-web = "4"
cats = { path = "../../libs/cats" }
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Now, let's update the application's code itself.
use actix_web::{App, HttpServer};
use cats::{create_cat_data, create_cat_scope};
async fn main() -> std::io::Result<()> {
// HttpServer:new creates multiple threads to handle requests.
// We need to make sure that the shared cat data is created once before the HttpServer
// We can then pass this reference to the create_cat_scope so that all threads have access to the same data
let cat_data = create_cat_data();
HttpServer::new(move || App::new().service(create_cat_scope(&cat_data)))
.bind(("127.0.0.1", 8080))?
.run()
.await
}
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