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

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



GraphQL ist eine leistungsstarke Abfragesprache für APIs, die es Clients ermöglicht, nur die Daten anzufordern, die sie benötigen. In Kombination mit der Leistung und Sicherheit von Rust erhalten Sie eine ideale Lösung für hochbelastete Webdienste. In diesem Tutorial erstellen wir eine vollständige GraphQL-API von Grund auf mit der Crate async-graphql.



Warum Rust? Es bietet Abstraktionen ohne Zusatzkosten, Speichersicherheit und beeindruckende Geschwindigkeit. GraphQL in Rust arbeitet schneller als vergleichbare Implementierungen in JavaScript oder Python, was für Produktionssysteme entscheidend ist.



1. Projekteinrichtung und Abhängigkeiten



Beginnen wir mit der Erstellung eines neuen Rust-Projekts. Öffnen Sie ein Terminal und führen Sie Folgendes aus:



cargo new graphql_rust_apicd graphql_rust_api


Fügen Sie nun die erforderlichen Abhängigkeiten in der Datei Cargo.toml hinzu:



[dependencies]async-graphql = "7.0"async-graphql-actix-web = "7.0"actix-web = "4"actix-cors = "0.7"serde = { version = "1.0", features = ["derive"] }tokio = { version = "1", features = ["full"] }


Diese Crates bieten alles Notwendige: async-graphql – den GraphQL-Kern, actix-web – den Webserver, serde – die Datenserialisierung.



2. Erstellung des Datenmodells und des Schemas



Definieren wir ein einfaches Modell für unsere API – Bücher. Erstellen wir die Strukturen und das GraphQL-Schema:



use async_graphql::*;use serde::{Serialize, Deserialize};

#[derive(Clone, Debug, Serialize, Deserialize, SimpleObject)]struct Book { id: ID, title: String, author: String, year: i32,}

#[derive(Clone, Debug, Serialize, Deserialize, InputObject)]struct BookInput { title: String, author: String, year: i32,}


Beachten Sie die Attribute #[derive(SimpleObject)] und #[derive(InputObject)]. Ersteres generiert automatisch den GraphQL-Typ für die Ausgabe, letzteres für die Dateneingabe.



3. Implementierung der Resolver (Query und Mutation)



Resolver sind Funktionen, die Anfragen verarbeiten. Erstellen wir eine Speicherstruktur und die Resolver:



use std::sync::Mutex;

struct QueryRoot;

#[Object]impl QueryRoot { async fn books(&self, ctx: &Context<'_>) -> Vec<Book> { let storage = ctx.data_unchecked::<Mutex<Vec<Book>>>(); storage.lock().unwrap().clone() }

async fn book(&self, ctx: &Context<'_>, id: ID) -> Option<Book> { let storage = ctx.data_unchecked::<Mutex<Vec<Book>>>(); storage.lock().unwrap().iter().find(|b| b.id == id).cloned() }}

struct MutationRoot;

#[Object]impl MutationRoot { async fn add_book(&self, ctx: &Context<'_>, input: BookInput) -> Book { let mut storage = ctx.data_unchecked::<Mutex<Vec<Book>>>() .lock().unwrap(); let book = Book { id: ID::from(storage.len() + 1), title: input.title, author: input.author, year: input.year, }; storage.push(book.clone()); book }}


Wir verwenden Mutex für den threadsicheren Zugriff auf die Daten. In einem echten Projekt würden Sie eine Datenbank anbinden, aber für dieses Tutorial ist dies eine ideale Lösung.



4. Zusammenbau und Start des Servers



Der letzte Schritt besteht darin, alles zu einem funktionierenden Server zusammenzufügen. Erstellen wir den Einstiegspunkt:



use actix_web::{guard, web, App, HttpServer, HttpRequest, HttpResponse};use actix_cors::Cors;use async_graphql_actix_web::{GraphQLRequest, GraphQLResponse};

async fn index( schema: web::Data<Schema<QueryRoot, MutationRoot, EmptySubscription>>, req: GraphQLRequest,) -> GraphQLResponse { schema.execute(req.into_inner()).await.into()}

#[actix_web::main]async fn main() -> std::

Blogs

Buchempfehlungen