GraphQL API con Rust: tutorial paso a paso para principiantes

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción a GraphQL API en Rust

El desarrollo web moderno requiere API flexibles y de alto rendimiento. GraphQL es un lenguaje de consulta que permite a los clientes obtener exactamente los datos que necesitan, sin redundancia. Rust, por su parte, ofrece alto rendimiento y seguridad en la memoria. En este tutorial crearemos un servidor GraphQL simple pero completo en Rust utilizando la biblioteca async-graphql. Aprenderás a configurar el proyecto, definir tipos de datos, escribir resolutores y ejecutar el servidor. El artículo está dirigido a desarrolladores principiantes familiarizados con los fundamentos de Rust.



Configuración del proyecto e instalación de dependencias

Para empezar, crearemos un nuevo proyecto Rust con Cargo:

cargo new graphql-rust-tutorialcd graphql-rust-tutorial

Abre el archivo Cargo.toml y agrega las siguientes dependencias:

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

Explicamos la elección de las bibliotecas:

  • async-graphql — la biblioteca principal para trabajar con GraphQL en Rust.
  • async-graphql-actix-web — integración con el framework web Actix-web.
  • actix-web — un popular servidor HTTP asíncrono.
  • serde — para serialización/deserialización de datos.
  • tokio — runtime asíncrono.

Ejecuta cargo build para asegurarte de que todas las dependencias estén instaladas correctamente.



Definición del esquema GraphQL y resolutores

Crearemos un modelo de datos simple: un libro. Definiremos la estructura y los resolutores para consultas y mutaciones.

Creación del modelo de datos

Crea el archivo src/models.rs y agrega el siguiente código:

use async_graphql::*;

#[derive(SimpleObject)]pub struct Book { pub id: ID, pub title: String, pub author: String,}

#[derive(InputObject)]pub struct NewBook { pub title: String, pub author: String,}

Aquí, SimpleObject genera automáticamente el tipo GraphQL para la estructura Book, y InputObject para los datos de entrada de la mutación.



Creación del almacenamiento y resolutores

Crearemos el archivo src/resolvers.rs, que contendrá la lógica de consultas y mutaciones:

use std::sync::Mutex;use async_graphql::*;use crate::models::{Book, NewBook};

pub struct QueryRoot;

#[Object]impl QueryRoot { async fn books(&self) -> Vec<Book> { let storage = STORAGE.lock().unwrap(); storage.clone() }

async fn book(&self, id: ID) -> Option<Book> { let storage = STORAGE.lock().unwrap(); storage.iter().find(|b| b.id == id).cloned() }}

pub struct MutationRoot;

#[Object]impl MutationRoot { async fn add_book(&self, input: NewBook) -> Book { let mut storage = STORAGE.lock().unwrap(); let new_book = Book { id: ID::from(format!("book_{}", storage.len() + 1)), title: input.title, author: input.author, }; storage.push(new_book.clone()); new_book }}

lazy_static::lazy_static! { static ref STORAGE: Mutex<Vec<Book>> = Mutex::new(vec![]);}

Ten en cuenta: usamos Mutex para acceso seguro a los hilos al almacenamiento. En un proyecto real, es mejor usar una base de datos.



Ensamblaje del esquema

Ahora unimos todo en el archivo src/main.rs:

use actix_web::{web, App, HttpServer, HttpResponse, middleware};use async_graphql::{http::GraphiQLSource, EmptySubscription, Schema};use async_graphql_actix_web::{GraphQLRequest, GraphQLResponse};use std::sync::Arc;

mod models;mod resol

Blogs

Book Recommendations