Einleitung: Warum Rust für REST APIs?
Rust ist eine moderne systemnahe Programmiersprache, die die Leistung von C/C++ mit Speichersicherheit kombiniert. In den letzten Jahren wird sie aktiv für die Erstellung hochlastiger Webdienste und REST APIs eingesetzt. Dank des Frameworks Actix-web können Sie in nur 30 Minuten ein vollwertiges REST API in Rust schreiben, selbst wenn Sie gerade erst anfangen, die Sprache zu lernen.
In diesem Artikel erstellen wir eine einfache, aber funktionierende REST API zur Verwaltung einer Aufgabenliste (Todo List). Sie lernen:
- Ein Rust-Projekt mit Actix-web einzurichten
- CRUD-Operationen (Create, Read, Update, Delete) zu implementieren
- Mit JSON-Anfragen und -Antworten zu arbeiten
- Routing und Handler zu verwenden
Bereit? Los geht's!
Schritt 1: Projekteinrichtung und Installation der Abhängigkeiten
Stellen Sie zunächst sicher, dass Rust installiert ist. Falls nicht, führen Sie den folgenden Befehl aus:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shErstellen Sie ein neues Projekt:
cargo new rust_todo_apicd rust_todo_apiÖffnen Sie Cargo.toml und fügen Sie die folgenden Abhängigkeiten hinzu:
[dependencies]actix-web = "4"serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"tokio = { version = "1", features = ["full"] }Hierbei gilt:
- actix-web — ein leistungsstarkes asynchrones Web-Framework
- serde — für die Serialisierung/Deserialisierung von JSON
- tokio — eine asynchrone Laufzeitumgebung (Actix-web verwendet sie unter der Haube)
Führen Sie cargo build aus, um die Abhängigkeiten herunterzuladen und zu kompilieren. Dies dauert 2-3 Minuten.
Schritt 2: Erstellung des Datenmodells und des Speichers
In diesem Projekt werden wir keine Datenbank anbinden — der Einfachheit halber verwenden wir einen Vektor im Speicher. Erstellen wir eine Struktur für die Aufgabe.
Öffnen Sie src/main.rs und schreiben Sie den folgenden Code:
use actix_web::{web, App, HttpServer, HttpResponse, middleware};use serde::{Deserialize, Serialize};use std::sync::Mutex;
// Aufgabenmodell#[derive(Serialize, Deserialize, Clone)]struct Task { id: u32, title: String, completed: bool,}
// Aufgabenspeicher (threadsicher)struct AppState { tasks: Mutex<Vec<Task>>,}Erläuterungen:
- #[derive(Serialize, Deserialize)] — generiert automatisch Methoden für die Arbeit mit JSON
- Mutex — gewährleistet sicheren Zugriff auf Daten aus mehreren Threads
- AppState — wird im Zustand der Anwendung gespeichert
Schritt 3: Implementierung der CRUD-Handler
Jetzt fügen wir Handler-Funktionen für jede HTTP-Methode hinzu. Fügen Sie den folgenden Code nach der Deklaration der Strukturen ein:
// Alle Aufgaben abrufenasync fn get_tasks(data: web::Data<AppState>) -> HttpResponse { let tasks = data.tasks.lock().unwrap(); HttpResponse::Ok().json(tasks.clone())}
// Neue Aufgabe erstellenasync fn create_task(data: web::Data<AppState>, body: web::Json<Task>) -> HttpResponse { let mut tasks = data.tasks.lock().unwrap(); let new_id = tasks.len() as u32 + 1; let task = Task { id: new_id, title: body.title.clone(), completed: body.completed, }; tasks.push(task.clone()); HttpResponse::Created().json(task)}
// Aufgabe aktualisierenasync fn update_task( data: web::Data<AppState>, path: web::Path<u32>, body: web::Json<Task>,) -> HttpResponse { let mut tasks = data.tasks.lock().unwrap(); let id = path.into_inner(); if let Some(task) = tasks.iter_mut().find(|t| t.id == id) { task.title = body.title.clone(); task.completed = body.completed; HttpRespons