Cargo workspace, monorepo for Rust
Cargo workspace, monorepo for Rust
Cargo workspace har ett eller flere cargo prosjekter i seg. Dette egner seg godt for monorepoer og er en god måte å dele kode for tjenester i samme domenet.
Det finnes en workspace plugin for cargo, men vi har valgt å ikke bruke den, da den ikke gir oss noen verdi.
For å starte med workspace så må du lage en katalog for monorepoet ditt, det vi her har navngitt my_monorepo.
mkdir my_monorepo
cd my_monorepo
Inne i workspace katalogen så trenger vi en Cargo.toml fil, denne for å fortelle cargo hvilke prosjekter den skal compilere.
echo '[workspace]' > ./Cargo.toml
Vi legger til prosjektene vi skal ha i monorepoet som medlemmer av workspacet.
Vi har her valgt ett gRPC endepunkt, ett GraphQL endepunkt og ett delt repository.
[workspace]
members = [
"grpc",
"repository",
"graphql",
]
Først legger vi til prosjektet gRPC, --bin
er default, så vi kan bruke bare
cargo new grpc
Gå så inn i det prosjektet.
cd grpc
Her kan vi legge til avhengigheter fra crates.io med cargo add
.
cargo add tonic
Vi kan også legge til workspace members med cargo add
og cargo vil da velge workspace members først, hvis det ikke finnes så går den til crates.io.
Her kan du lese mer om cargo add
cargo add repository
Vi har valgt å bruke github i stedet for en privat registry service, for å hente inn fra felles repo
cargo add toolshed-config --git https://github.com/amedia/toolshed-rust
Vi får da en Cargo.toml
som ser ut som dette:
[package]
name = "grpc"
version = "0.1.0"
edition = "2021"
[dependencies]
repository = { version = "0.1.0", path = "../repository" }
tonic = "0.8.3"
toolshed-config = { git = "https://github.com/amedia/toolshed-rust", version = "0.1.0" }
Lokale avhengigheter/biblioteker og github repos, refereres til i koden på lik linje med tredjepartsbiblioteker.
//Fra samme workspace
use repository::*;
//Fra crates.io
use tonic::*;
//Fra private github repo
use toolshed-rust::*;
Repository er ett delt bibliotek, så her legger vi til --lib
flagget bak cargo new
cargo new repository --lib
cd repository
Rust har ikke runtime, men noen biblioteker trenger det for blant annet async, vi legger til actix rustls
cargo add sqlx -F runtime-actix-rustls
Vi får da Cargo.toml
fila:
[package]
name = "repository"
version = "0.1.0"
edition = "2021"
[dependencies]
sqlx = { version = "0.6.2", features = ["runtime-actix-rustls"] }
Så legger vi til det tredje prosjektet, som er ett GraphQL endepunkt, hvor vi bruker Juniper og Actix-Web integrasjonen.
cargo new graphql
cd graphql
cargo add repository
cargo add actix-web
cargo add juniper
Vi får da en Cargo.toml
fil som ser noe sånt ut:
[package]
name = "graphql"
version = "0.1.0"
edition = "2021"
[dependencies]
repository = { version = "0.1.0", path = "../repository" }
actix-web = "4.2.1"
juniper = "0.15.10"
Prosjekttreet skal da se noe sånt ut. Legg merke til at Cargo.lock
fila er på rotnivå i workspacet.
Dette blir da sub-domenet my_monorepo
hvor da repository
er ett lib
inne i de to tjenestene.
Man kan bygge hele workspacet fra toppnivå med:
cargo build
Applikasjonene kan startes fra toppnivå med:
cargo run -p grpc
Eller kan startes fra det respektive prosjektet med bare
cargo run