Wie man in 30 Minuten eine REST API in Rust schreibt: für Anfänger

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum Rust für REST APIs?

Rust ist eine moderne systemnahe Programmiersprache, die die Leistung von C++ mit Speichersicherheit kombiniert. In den letzten Jahren ist sie zu einer beliebten Wahl für die Erstellung hochbelastbarer Webdienste geworden. Wenn Sie bereits mit Python vertraut sind und etwas Neues ausprobieren möchten, ist Rust ein ausgezeichneter nächster Schritt.

In diesem Artikel erstellen wir eine vollständige REST API zur Verwaltung einer Aufgabenliste (Todo List) in Rust unter Verwendung des Frameworks Actix-web. Der gesamte Prozess dauert nicht länger als 30 Minuten, wenn Sie der Anleitung folgen.



1. Vorbereitung der Umgebung

Rust installieren

Wenn Sie Rust noch nicht installiert haben, führen Sie den folgenden Befehl im Terminal aus (Linux/macOS):

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Für Windows laden Sie das Installationsprogramm von der offiziellen Website herunter.

Überprüfen Sie nach der Installation die Version:

rustc --version


Projekt erstellen

Erstellen wir ein neues Projekt mit Cargo, dem Paketmanager von Rust:

cargo new rust_todo_apicd rust_todo_api


Abhängigkeiten hinzufügen

Öffnen Sie die Datei Cargo.toml und fügen Sie die folgenden Abhängigkeiten hinzu:

[dependencies]actix-web = "4"actix-rt = "2"serde = { version = "1", features = ["derive"] }serde_json = "1"tokio = { version = "1", features = ["full"] }

Speichern Sie die Datei. Cargo lädt beim ersten Build automatisch alle Bibliotheken herunter.



2. Datenmodell und Speicher erstellen

Bevor wir Endpunkte schreiben, definieren wir die Datenstruktur. Wir verwenden einen einfachen Vektor im Speicher (zur Demonstration).



Aufgabenmodell

Erstellen Sie die Datei src/models.rs:

use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone)]pub struct Task { pub id: u32, pub title: String, pub completed: bool,}


Globaler Speicher

In src/main.rs fügen wir einen globalen Zustand hinzu. Für die Threadsicherheit verwenden wir Mutex:

use std::sync::Mutex;use actix_web::{web, App, HttpServer, HttpResponse, HttpRequest, Responder};use models::Task;

mod models;

struct AppState { tasks: Mutex<Vec<Task>>, next_id: Mutex<u32>,}


3. Implementierung der CRUD-Endpunkte

Jetzt schreiben wir die wichtigsten Handler. Alle erhalten den Anwendungszustand über web::Data.



GET /tasks — alle Aufgaben abrufen

async fn get_tasks(data: web::Data<AppState>) -> impl Responder {    let tasks = data.tasks.lock().unwrap();    HttpResponse::Ok().json(tasks.clone())}


POST /tasks — neue Aufgabe erstellen

async fn create_task(data: web::Data<AppState>, body: web::Json<Task>) -> impl Responder {    let mut tasks = data.tasks.lock().unwrap();    let mut next_id = data.next_id.lock().unwrap();    let new_task = Task {        id: *next_id,        title: body.title.clone(),        completed: false,    };    tasks.push(new_task.clone());    *next_id += 1;    HttpResponse::Created().json(new_task)}


GET /tasks/{id} — Aufgabe nach ID abrufen

async fn get_task(data: web::Data<AppState>, path: web::Path<u32>) -> impl Responder {    let id = path.into_inner();    let tasks = data.tasks.lock().unwrap();    match tasks.iter().find(|t| t.id == id) {        Some(task) => HttpResponse::Ok().json(task),        None => HttpResponse::NotFound().json("Task not found"),    }}


DELETE /tasks/{id} — Aufgabe löschen

async fn delete_task(data: web::Data<AppState>, path: web::Path<u32>) -> impl Responder {    let id = path.into_inner();    l                

Blogs

Buchempfehlungen