GraphQL API com Rust: tutorial passo a passo para iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução à API GraphQL em Rust

O desenvolvimento web moderno exige APIs flexíveis e performáticas. GraphQL é uma linguagem de consulta que permite aos clientes obter exatamente os dados de que precisam, sem redundância. Rust, por sua vez, oferece alta performance e segurança de memória. Neste tutorial, criaremos um servidor GraphQL simples, mas completo, em Rust usando a biblioteca async-graphql. Você aprenderá a configurar o projeto, definir tipos de dados, escrever resolvers e iniciar o servidor. O artigo é voltado para desenvolvedores iniciantes familiarizados com os fundamentos do Rust.



Configuração do projeto e instalação de dependências

Para começar, vamos criar um novo projeto Rust com o Cargo:

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

Abra o arquivo Cargo.toml e adicione as seguintes dependências:

[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"] }

Explicando a escolha das bibliotecas:

  • async-graphql — biblioteca principal para trabalhar com GraphQL em Rust.
  • async-graphql-actix-web — integração com o framework web Actix-web.
  • actix-web — servidor HTTP assíncrono popular.
  • serde — para serialização/desserialização de dados.
  • tokio — runtime assíncrono.

Execute cargo build para verificar se todas as dependências foram instaladas corretamente.



Definição do esquema GraphQL e resolvers

Vamos criar um modelo de dados simples — um livro. Definiremos a estrutura e os resolvers para consultas e mutações.

Criação do modelo de dados

Crie o arquivo src/models.rs e adicione o seguinte 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,}

Aqui, SimpleObject gera automaticamente o tipo GraphQL para a estrutura Book, e InputObject para os dados de entrada da mutação.



Criação do armazenamento e resolvers

Vamos criar o arquivo src/resolvers.rs, que conterá a lógica das consultas e mutações:

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![]);}

Observe: usamos Mutex para acesso thread-safe ao armazenamento. Em um projeto real, é melhor usar um banco de dados.



Montagem do esquema

Agora, vamos unir tudo no arquivo 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