Rustango docs
← Premiers pas

Scaffolding

Rustango dispose de deux niveaux de génération de code — de sorte que vous n'avez presque jamais à câbler de code répétitif à la main :

  1. Le générateur de projet — cargo rustango new crée un tout nouveau projet à partir d'un template.
  2. Les générateurs internes au projet — manage startapp et la famille manage make:* ajoutent des apps, des vues, des sérialiseurs, des jobs, et bien plus au sein d'un projet existant.

cargo rustango new scaffolds a complete, ready-to-run project — Cargo manifest, config tiers, Docker, migrations, and src — in one command

Table des matières


Installer le générateur

cargo rustango est une sous-commande Cargo. Installez-la une fois, globalement :

cargo install cargo-rustango

Cela place un binaire cargo-rustango sur votre PATH ; Cargo l'expose alors comme cargo rustango — une commande globale disponible partout, même en dehors d'un projet.

La version du générateur est celle que votre projet obtient

cargo rustango new écrit rustango = "MAJOR.MINOR" dans le Cargo.toml généré, en reprenant la version du générateur, et non la plus récente publiée sur crates.io. Quel que soit le générateur que vous installez, c'est la version que votre projet épingle.

C'est presque toujours ce que vous voulez, et c'est pour cela que la commande d'installation ci-dessus n'est pas épinglée : le générateur le plus récent écrit l'épinglage le plus récent, et les deux ne peuvent pas diverger.

Cela vaut la peine de le savoir lorsque vous voulez délibérément une version plus ancienne — pour coller à un projet qui y est déjà, ou pour reproduire un rapport. Épinglez le générateur, pas le projet :

cargo install cargo-rustango --version 0.57.0

Vérifiez laquelle vous avez avec cargo rustango --version. Mettre à jour plus tard, c'est la même commande avec --force, et cela n'affecte que les projets que vous générez ensuite — l'épinglage d'un projet existant est une ligne dans son propre Cargo.toml, que vous modifiez vous-même.


Créer un projet : cargo rustango new

cargo rustango new <name> [--template api|fullstack|tenant]
                          [--backend postgres|sqlite|mysql]
                          [--features <liste>]
  • <name> — le nom du projet (et de la crate). Il doit s'agir d'un nom de crate Cargo valide ([A-Za-z_][A-Za-z0-9_-]*), et le répertoire cible ne doit pas déjà exister.
  • --template / -t — quel template utiliser pour l'échafaudage (par défaut : fullstack).
  • --backend / -b — sur quelle base de données le projet tourne (par défaut : postgres).
  • --features / -F — fonctionnalités Rustango supplémentaires, séparées par des virgules ou des espaces.
  • --interactive / -i — choisir dans des menus à la place. Un cargo rustango new nu sur un terminal fait de même.
  • --help / -h, --version — usage et version.

Lancé sans argument, il pose les questions :

  rustango — new project
  (enter accepts the default; ctrl-c aborts)

  Project name: shop

  Template
    1) fullstack  ORM + auto-admin + forms — the usual starting point  (default)
    2) api        bare ORM + axum, no admin UI — for JSON-only services
    3) tenant     multi-tenancy: tenant registry + operator console
  > 3

  Database
    1) postgres  every feature, including schema-mode tenancy  (default)
    2) sqlite    a file beside the project — no server to run
    3) mysql     MySQL 8.0+ / MariaDB
  > 1

  Extra features  (numbers, e.g. `1 3 4` — enter for none)
     1) csrf         CSRF protection middleware for form POSTs
     2) sso          OIDC single sign-on for application users
     …
  > 1 2

  Same thing without the wizard:
    cargo rustango new shop --template tenant --backend postgres --features csrf,sso

  Create it? [Y/n]

L'assistant règle exactement les champs que règlent les flags et affiche la ligne de commande équivalente avant d'écrire quoi que ce soit — s'en servir une fois vous apprend les flags, et un seul chemin de code décide de ce que contient un projet. Sans terminal (script, job CI), il échoue avec un message au lieu d'attendre une réponse que personne n'est là pour donner.

Les trois templates

Chacun correspond à une des trois formes d'application de Rustango :

TemplateCe que vous obtenezÀ utiliser quand
apiORM nu + Axum, sans adminServices et microservices JSON uniquement
fullstack (par défaut)ORM + l'admin automatiqueUne application web classique avec un back-office
tenantMulti-tenancy + console opérateur + apps par tenantHébergement SaaS avec de nombreux tenants isolés
cargo rustango new myblog                      # fullstack (the default)
cargo rustango new api_demo  --template api
cargo rustango new shop      --template tenant

Choisir la base de données : --backend

cargo rustango new edge --backend sqlite
cargo rustango new shop --backend mysql

--backend décide de ce qu'utilise cargo run, et façonne tout le projet en conséquence — la DATABASE_URL dans .env.example, les services de docker-compose.yml, l'url de chaque palier de configuration et les instructions de démarrage du README. Choisissez sqlite et il n'y a aucun service de base de données : c'est un fichier à côté du projet, créé par le premier cargo run -- migrate.

Les trois backends restent câblés dans les [features] générées, les deux autres sont donc à un flag :

cargo run --no-default-features --features sqlite

Activer plus du framework : --features

cargo rustango new saas --template tenant --features csrf,sso,cache-redis

Un template active un ensemble raisonnable ; --features ajoute les options qu'aucun d'eux n'atteint :

FonctionnalitéCe qu'elle ajoute
tenancyMulti-tenancy : registry de tenants, bases par tenant, console opérateur
csrfMiddleware de protection CSRF pour les POST de formulaires
sso / admin-ssoAuthentification unique OIDC, pour les utilisateurs / pour le site d'admin
passkeyAuthentification WebAuthn / passkey
cache-redis / cache-pageBackend de cache Redis / mise en cache de pages entières
jobs / jobs-postgresFile de tâches en arrière-plan, en processus / adossée à la base et donc résistante aux redémarrages
schedulerTâches d'arrière-plan à intervalle fixe
email-smtpTransport SMTP pour le framework e-mail
mcpServeur Model Context Protocol pour les agents IA
testkit / test_utilsConstructeurs de schéma, fabriques et constructeurs réservés aux tests

cargo rustango new --help affiche cette liste. Les backends ne sont pas valides ici — passez par --backend. En nommer un comme fonctionnalité est refusé : cela figerait le backend du framework alors que la fonctionnalité propre au projet resterait éteinte, et #[derive(Model)] aligne ses émissions sur les fonctionnalités du projet.


Ce qui est généré

Chaque template écrit un projet Cargo autonome :

<name>/
  Cargo.toml            # the rustango dependency + features for this template
  .env.example          # copy to .env (DATABASE_URL, RUSTANGO_SESSION_SECRET, …)
  .gitignore
  rust-toolchain.toml   # selects the `stable` toolchain + rustfmt/clippy/rust-analyzer
  docker-compose.yml    # a Postgres service to develop against
  Dockerfile            # production image
  README.md
  config/
    default.toml        # settings shared across every environment
    dev_settings.toml   # per-tier overrides …
    staging_settings.toml
    prod_settings.toml
  migrations/           # JSON migration files (committed to git)
  src/
    main.rs             # the single binary — HTTP server + every manage verb
    models.rs           # your #[derive(Model)] structs
    views.rs            # request handlers ("views")
    urls.rs             # pub fn api() -> Router that aggregates your routes

Un seul binaire pour tout

src/main.rs est le seul point d'entrée. Il démarre le serveur HTTP et dispatche chaque verbe manage — il n'y a pas de manage.py séparé ni de src/bin/manage.rs :

mod models;
mod urls;
mod views;

#[rustango::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let _ = dotenvy::dotenv();
    rustango::manage::Cli::new()
        .api(urls::api())
        .with_welcome()  // friendly `/` page until you add a root handler
        .with_health()   // /health + /ready endpoints (fullstack & tenant)
        .run()
        .await
}

Ainsi, cargo run démarre le serveur, et cargo run -- <verb> exécute les migrations, les générateurs, et le reste.

En quoi les templates diffèrent à l'intérieur de main.rs / urls.rs :

  • api — pas d'admin ; urls::api() se contente d'agréger vos propres routes.
  • fullstack — le même urls.rs, plus la fonctionnalité admin compilée dedans. L'admin n'est pas câblé pour vous : rien de ce qui est généré ne l'appellerait, donc le générateur n'émet aucun admin_router. Ajoutez-en un vous-même et imbriquez-le — Prise en main, étape 11 l'explique en détail. Prenez un rustango::sql::Pool pour que l'assistant ne nomme aucun pilote.
  • tenant — main.rs ajoute .tenancy(), servant la console opérateur sur le domaine apex et chaque tenant sous son propre sous-domaine. Les propres tables du framework sont générées dans un dossier system/migrations/ à partir des modèles compilés lors du premier cargo run -- migrate — aucun JSON de bootstrap livré à la main, donc le tout premier migrate fonctionne sans configuration supplémentaire.

Configuration en couches

Les paramètres se chargent d'abord depuis config/default.toml, puis depuis config/<RUSTANGO_ENV>_settings.toml par-dessus. RUSTANGO_ENV vaut dev par défaut, si bien qu'un cargo run juste après l'échafaudage fonctionne sans aucune modification ; définissez RUSTANGO_ENV=prod en production pour prendre en compte prod_settings.toml.

Premier lancement

cd <name>
cp .env.example .env
docker compose up -d        # start Postgres
cargo run -- migrate        # apply migrations
cargo run                   # serve
cargo run -- --help         # see every manage verb

Ajouter un module fonctionnel : manage startapp

Il échafaude un module autonome regroupant des modèles, des vues et des routes liés entre eux :

cargo run -- startapp blog

Cela écrit src/blog/ contenant mod.rs, models.rs (un modèle de départ nommé d'après l'app mise au singulier — blog → Blog), views.rs, urls.rs, et tests.rs, puis déclare le module dans src/main.rs et fusionne ses routes dans urls::api().

Options :

  • --into <dir> — échafaude sous un répertoire de base autre que src/ (par exemple un membre de workspace).
  • --with-manage-bin — génère aussi un bin/manage.rs (pour les architectures qui préfèrent un binaire manage séparé).

Générer des fichiers individuels : les commandes make:*

Au sein d'un projet, les verbes make:* échafaudent un fichier à la fois. La référence complète, drapeau par drapeau, se trouve dans la référence CLI manage ; les formes les plus courantes sont :

CommandeGénère
make:viewset <Name> [--model <M>]Un ViewSet CRUD
make:serializer <Name> [--model <M>]Un sérialiseur pour la mise en forme des requêtes/réponses
make:api_routes <app>Un agrégateur de routes API pour une app
make:form <Name>Un formulaire HTML avec validation
make:job <Name>Un gestionnaire de job en arrière-plan
make:notification <Name>Une notification multi-canal
make:middleware <Name>Un squelette de middleware
make:test <Name>Un module de test utilisant le client de test in-process
cargo run -- make:viewset PostViewSet --model Post
cargo run -- make:serializer PostSerializer --model Post
cargo run -- make:test post_smoke

Un flux typique

cargo rustango new myblog                              # 1. scaffold the project
cd myblog
cargo run -- startapp blog                             # 2. add a feature module
# …add fields to src/blog/models.rs…
cargo run -- makemigrations                            # 3. generate a migration
cargo run -- migrate                                   # 4. apply it
cargo run -- make:viewset PostViewSet --model Post     # 5. expose a JSON API
cargo run                                              # 6. serve