Projekteinrichtung
Die API strukturieren
Projekteinrichtung ist eine kostenlose Learn Rust Coding-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Learn Rust Coding-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Learn Rust Coding-Kurs umfasst insgesamt 4 Lektionen.
Eine REST-API in Rust erstellen
In diesem Kurs erstellen Sie eine kleine REST-API in Rust. Wir verwenden das Web-Framework Axum, das auf Tokio (asynchrone Laufzeitumgebung) und Tower (Middleware) aufbaut. Es ist ergonomisch, typsicher und wird häufig in Produktionsumgebungen eingesetzt.
In dieser ersten Lektion richten Sie die Projektstruktur ein, damit spätere Lektionen Routen, Modelle, eine Datenbank und Tests hinzufügen können.
Das Projekt erstellen
Beginnen Sie mit Cargo. Ein Binärprojekt stellt einen Einstiegspunkt src/main.rs bereit:
cargo new rest_apierstellt den Ordner.cd rest_apiwechselt in diesen Ordner.cargo runerstellt und startet das Projekt.
Dies sind Shell- und Cargo-Befehle, keine ausführbaren Rust-Codeausschnitte.
// terminal
// cargo new rest_api
// cd rest_api
// cargo runAbhängigkeiten hinzufügen
Eine Axum-API benötigt einige Crates in Cargo.toml:
axumfür Routing und Handler.tokiofür die asynchrone Laufzeitumgebung.serdefür die JSON-Serialisierung.
// Cargo.toml
// [dependencies]
// axum = "0.7"
// tokio = { version = "1", features = ["full"] }
// serde = { version = "1", features = ["derive"] }
// serde_json = "1"Die asynchrone Laufzeitumgebung
Webserver verarbeiten viele Verbindungen gleichzeitig, daher ist Axum asynchron. Das Attribut #[tokio::main] verwandelt eine asynchrone main-Funktion in einen echten Einstiegspunkt, indem es die Tokio-Laufzeitumgebung startet. Jeder Handler kann .await für nicht blockierende Ein-/Ausgabe verwenden.
// src/main.rs
use tokio;
#[tokio::main]
async fn main() {
println!("runtime started");
}Ein minimaler Server
Die kleinste Axum-Anwendung erstellt einen Router, bindet einen TCP-Listener und startet den Server. Eine einzelne Route ordnet GET / einem Handler zu, der eine Zeichenkette zurückgibt. Handler sind einfach asynchrone Funktionen, die etwas zurückgeben, das IntoResponse implementiert.
use axum::{routing::get, Router};
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(root));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await.unwrap();
axum::serve(listener, app).await.unwrap();
}
async fn root() -> &'static str {
"Hello, API!"
}So funktioniert Routing
Ein Router ordnet einen Pfad und eine HTTP-Methode einem Handler zu. Verketten Sie Aufrufe von .route(path, method(handler)), um Endpunkte zu registrieren. Methodenhilfen wie get, post, put und delete stammen aus axum::routing. Sie können mehrere Methoden für denselben Pfad kombinieren.
use axum::{routing::{get, post}, Router};
async fn list() -> &'static str { "list" }
async fn create() -> &'static str { "created" }
fn build_router() -> Router {
Router::new()
.route("/items", get(list).post(create))
.route("/health", get(|| async { "ok" }))
}Empfohlene Modulstruktur
Wenn die API wächst, teilen Sie den Code in Module auf, statt eine einzige große Datei main.rs zu verwenden:
main.rs— Start und Serverkonfiguration.routes.rs— Definition des Routers.handlers.rs— Request-Handler.models.rs— Datenstrukturen.
Diese Trennung hält jede Datei übersichtlich und testbar.
// src/main.rs
mod routes;
mod handlers;
mod models;
#[tokio::main]
async fn main() {
let app = routes::build();
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await.unwrap();
axum::serve(listener, app).await.unwrap();
}Gemeinsam genutzter Anwendungszustand
Die meisten APIs benötigen einen gemeinsam genutzten Zustand, etwa einen Datenbank-Pool oder einen In-Memory-Speicher. Axum verwaltet ihn mit .with_state(state) am Router. Handler erhalten ihn über den Extractor State. Der Zustand muss Clone implementieren; veränderliche Daten sollten Sie in Arc und einer Sperre kapseln.
use axum::{routing::get, Router, extract::State};
use std::sync::{Arc, Mutex};
type Db = Arc<Mutex<Vec<String>>>;
async fn count(State(db): State<Db>) -> String {
let n = db.lock().unwrap().len();
format!("{} items", n)
}
fn build(db: Db) -> Router {
Router::new().route("/count", get(count)).with_state(db)
}JSON zurückgeben
Um JSON zu senden, kapseln Sie einen serialisierbaren Wert in axum::Json. Wenn Sie bei Ihren Structs mit serde Serialize ableiten, setzt Axum den richtigen Inhaltstyp und den Body automatisch.
use axum::Json;
use serde::Serialize;
#[derive(Serialize)]
struct Status {
service: String,
healthy: bool,
}
async fn health() -> Json<Status> {
Json(Status { service: "api".into(), healthy: true })
}Konfiguration und Ports
Für Demos ist ein fest codierter Port in Ordnung, echte Dienste lesen die Konfiguration jedoch aus der Umgebung. Verwenden Sie std::env::var mit einem Standardwert. So können Sie die Bind-Adresse ändern, ohne neu zu kompilieren, und die Anwendung problemlos in Containern ausführen.
use std::env;
async fn main_inner() {
let port = env::var("PORT").unwrap_or_else(|_| "3000".to_string());
let addr = format!("0.0.0.0:{}", port);
println!("binding to {}", addr);
// bind and serve with addr ...
}Die Einrichtung zusammenführen
Beim vollständigen Startvorgang wird alles miteinander verbunden: Erstellen Sie den Router mit Routen und gemeinsam genutztem Zustand, lesen Sie den Port ein, binden Sie einen Listener und starten Sie den Server. Mit diesem Grundgerüst können die nächsten Lektionen echte Endpunkte, Modelle und Persistenz hinzufügen.
use axum::{routing::get, Router};
use std::sync::{Arc, Mutex};
#[tokio::main]
async fn main() {
let db = Arc::new(Mutex::new(Vec::<String>::new()));
let app = Router::new()
.route("/health", get(|| async { "ok" }))
.with_state(db);
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
.await.unwrap();
axum::serve(listener, app).await.unwrap();
}Kurze Verständnisprüfung
Testen Sie Ihr Verständnis der Projekte Einrichtung.
Zusammenfassung
Sie haben ein Rust-REST-API-Projekt eingerichtet:
- Verwenden Sie
cargo newund fügen Sieaxum,tokioundserdehinzu. #[tokio::main]stellt die asynchrone Laufzeitumgebung bereit.- Ein
Routerordnet Pfade und Methoden asynchronen Handlern zu. - Teilen Sie Daten mit
.with_stateund dem ExtractorState. - Teilen Sie den Code in Routen-, Handler- und Modellmodule auf und lesen Sie den Port aus der Umgebung.
Häufig gestellte Fragen
Ist die Lektion „Projekteinrichtung“ kostenlos?
Ja — der vollständige Text von „Projekteinrichtung“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Learn Rust Coding-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Learn Rust Coding-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Projekteinrichtung“?
Die API strukturieren Du übst Learn Rust Coding mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Learn Rust Coding zu starten?
Keine Vorkenntnisse erforderlich. Learn Rust Coding auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.
Wie lange dauert die Lektion „Projekteinrichtung“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Learn Rust Coding-Lektion Code schreiben und ausführen?
Ja. Jede Learn Rust Coding-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Projekteinrichtung
- Endpoints und Modelle
- Datenbankintegration
- Die API testen