GraphQL API mit Rust: Schritt-für-Schritt-Tutorial in der Praxis

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 und GraphQL ein ideales Paar sind

\n

Moderne Webentwicklung erfordert hohe Leistung und strenge Typisierung. Rust, bekannt für seine Speichersicherheit und Geschwindigkeit, ist eine ausgezeichnete Wahl für die Backend-Entwicklung. GraphQL wiederum bietet eine flexible und effiziente Möglichkeit, mit Daten zu arbeiten. In diesem Tutorial erstellen wir eine vollständige GraphQL API in Rust unter Verwendung der Bibliothek async-graphql und des Frameworks actix-web. Sie lernen, Schemata zu definieren, Resolver zu schreiben und Anfragen zu verarbeiten.

\n

Am Ende des Artikels haben Sie einen funktionierenden Server, der für die Integration in reale Projekte bereit ist. Alle Codebeispiele sind getestet und lauffähig.

\n\n

Projekt einrichten und Abhängigkeiten installieren

\n

Zunächst erstellen wir ein neues Rust-Projekt. Stellen Sie sicher, dass Rust installiert ist (empfohlen wird Version 1.75+).

\n
cargo new graphql-rust-api\ncd graphql-rust-api
\n

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

\n
[dependencies]\nactix-web = "4"\nactix-rt = "2"\nasync-graphql = "7"\nasync-graphql-actix-web = "7"\nserde = { version = "1", features = ["derive"] }\ntokio = { version = "1", features = ["macros"] }
\n

Führen Sie cargo build aus, um alle Abhängigkeiten herunterzuladen und zu kompilieren. Dies kann beim ersten Start einige Minuten dauern.

\n\n

Projektstruktur

\n

Erstellen Sie die folgende Ordner- und Dateistruktur:

\n
src/\n├── main.rs\n├── schema.rs\n├── models.rs\n└── resolvers.rs
\n

Wir werden jede Datei nach und nach befüllen.

\n\n

Modelle und GraphQL-Schema definieren

\n

Beginnen wir mit der Erstellung eines einfachen Datenmodells. In models.rs beschreiben wir die Struktur User:

\n
use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct User {\n    pub id: u32,\n    pub name: String,\n    pub email: String,\n}
\n

Kommen wir nun zu schema.rs. Hier definieren wir die GraphQL-Objekte und Abfragen:

\n
use async_graphql::{Context, Object, SimpleObject};\nuse crate::models::User;\nuse crate::resolvers::get_all_users;\n\n#[derive(SimpleObject)]\npub struct UserObject {\n    pub id: u32,\n    pub name: String,\n    pub email: String,\n}\n\npub struct QueryRoot;\n\n#[Object]\nimpl QueryRoot {\n    async fn users(&self, ctx: &Context<'_>) -> Vec<UserObject> {\n        let users = get_all_users(ctx).await;\n        users.into_iter().map(|u| UserObject {\n            id: u.id,\n            name: u.name,\n            email: u.email,\n        }).collect()\n    }\n}
\n

Beachten Sie die Verwendung von #[derive(SimpleObject)] – dies ist ein Makro von async-graphql, das automatisch den GraphQL-Typ generiert.

\n\n

Resolver: Geschäftslogik

\n

In der Datei resolvers.rs implementieren wir die Funktion zum Abrufen von Daten. Der Einfachheit halber verwenden wir eine statische Liste:

\n
use async_graphql::Context;\nuse crate::models::User;\n\npub async fn get_all_users(_ctx: &Context<'_>) -> Vec<User> {\n    vec![\n        User { id: 1, name: "Alice".into(), email: "alice@example.com".into() },\n        User { id: 2, name: "Bob".into(), email: "bob@example.com".into() },\n        User { id: 3, name: "Charlie".into(), email: "charlie@example.com".into() },\n    ]\n}
\n

In einem realen Projekt könnte hier ein Zugriff auf eine Datenbank oder eine externe API stehen.

\n\n

Server mit Actix-web zusammenbauen

\n

Jetzt kommt der wichtigste Teil – alles in main.rs zusammenfügen:

\n
use actix_web::{web, App, HttpServer, HttpResponse};\nuse async_graphql::{Schema, EmptyMutation, EmptySubscription};\nuse async_graphql_actix_web::{GraphQLRequest, GraphQLResponse};\nuse crate::schema::QueryRoot;\n\nmod models;\nmod schema;\nmod resolvers;\n\ntype AppSchema = Schema<QueryRoot, EmptyMutation, EmptySubscription>;\n\nasync fn graphql_handler(\n    schema                

Blogs

Buchempfehlungen