API GraphQL avec Rust : tutoriel pratique étape par étape

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Introduction : pourquoi Rust et GraphQL forment une paire idéale

\n

Le développement web moderne exige des performances élevées et un typage strict. Rust, connu pour sa sécurité mémoire et sa rapidité, devient un excellent choix pour créer des backends. GraphQL, quant à lui, offre une manière flexible et efficace de travailler avec les données. Dans ce tutoriel, nous allons créer une API GraphQL complète en Rust, en utilisant la bibliothèque async-graphql et le framework actix-web. Vous apprendrez à définir des schémas, écrire des résolveurs et traiter des requêtes.

\n

À la fin de cet article, vous disposerez d'un serveur fonctionnel, prêt à être intégré dans des projets réels. Tous les exemples de code sont vérifiés et prêts à être exécutés.

\n\n

Configuration du projet et installation des dépendances

\n

Pour commencer, créons un nouveau projet Rust. Assurez-vous d'avoir Rust installé (version recommandée 1.75+).

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

Ouvrez Cargo.toml et ajoutez les dépendances suivantes :

\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

Exécutez cargo build pour télécharger et compiler toutes les dépendances. Cela peut prendre quelques minutes lors de la première exécution.

\n\n

Structure du projet

\n

Créez la structure de dossiers et fichiers suivante :

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

Nous allons remplir chaque fichier progressivement.

\n\n

Définition des modèles et du schéma GraphQL

\n

Commençons par créer un modèle de données simple. Dans models.rs, décrivons la structure 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

Passons maintenant à schema.rs. Ici, nous définirons les objets GraphQL et les requêtes :

\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

Notez l'utilisation de #[derive(SimpleObject)] — c'est une macro d'async-graphql qui génère automatiquement le type GraphQL.

\n\n

Résolveurs : logique métier

\n

Dans le fichier resolvers.rs, implémentons la fonction de récupération des données. Pour simplifier, nous utiliserons une liste statique :

\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

Dans un projet réel, cela pourrait être un appel à une base de données ou à une API externe.

\n\n

Assemblage du serveur avec Actix-web

\n

Vient maintenant l'étape la plus importante : assembler le tout dans main.rs :

\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

Book Recommendations