GraphQL API com Rust: tutorial prático passo a passo

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

GraphQL API com Rust: tutorial prático passo a passo



GraphQL é uma linguagem de consulta poderosa para APIs que permite aos clientes solicitarem apenas os dados de que precisam. Combinado com o desempenho e a segurança do Rust, você obtém uma solução ideal para serviços web de alta carga. Neste tutorial, criaremos uma API GraphQL completa do zero, usando a crate async-graphql.



Por que Rust? Ele oferece abstrações de custo zero, segurança de memória e velocidade impressionante. GraphQL em Rust é mais rápido que alternativas em JavaScript ou Python, o que é crítico para sistemas em produção.



1. Configuração do projeto e dependências



Vamos começar criando um novo projeto Rust. Abra o terminal e execute:



cargo new graphql_rust_apicd graphql_rust_api


Agora adicione as dependências necessárias no arquivo Cargo.toml:



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


Essas crates fornecem tudo o que é necessário: async-graphql — o núcleo do GraphQL, actix-web — o servidor web, serde — serialização de dados.



2. Criação do modelo de dados e esquema



Vamos definir um modelo simples para nossa API — livros. Criaremos as estruturas e o esquema GraphQL:



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,}


Observe os atributos #[derive(SimpleObject)] e #[derive(InputObject)]. O primeiro gera automaticamente um tipo GraphQL para saída, o segundo para entrada de dados.



3. Implementação dos resolvers (Query e Mutation)



Resolvers são funções que processam as consultas. Vamos criar a estrutura de armazenamento e os resolvers:



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 }}


Usamos Mutex para acesso thread-safe aos dados. Em um projeto real, você conectaria um banco de dados, mas para este tutorial é a opção ideal.



4. Montagem e inicialização do servidor



O passo final é unir tudo em um servidor funcional. Vamos criar o ponto de entrada:



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

Book Recommendations