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

Introdução: por que Rust e GraphQL são a combinação ideal

\n

O desenvolvimento web moderno exige alto desempenho e tipagem estrita. Rust, conhecido por sua segurança de memória e velocidade, torna-se uma excelente escolha para criar backends. GraphQL, por sua vez, oferece uma forma flexível e eficiente de trabalhar com dados. Neste tutorial, criaremos uma GraphQL API completa em Rust, usando a biblioteca async-graphql e o framework actix-web. Você aprenderá a definir esquemas, escrever resolvers e processar requisições.

\n

Ao final do artigo, você terá um servidor funcional, pronto para integração em projetos reais. Todos os exemplos de código foram testados e estão prontos para execução.

\n\n

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

\n

Para começar, vamos criar um novo projeto Rust. Certifique-se de ter o Rust instalado (versão recomendada: 1.75+).

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

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

\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

Execute cargo build para baixar e compilar todas as dependências. Isso pode levar alguns minutos na primeira execução.

\n\n

Estrutura do projeto

\n

Crie a seguinte estrutura de pastas e arquivos:

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

Vamos preencher cada arquivo gradualmente.

\n\n

Definição de modelos e esquema GraphQL

\n

Vamos começar criando um modelo de dados simples. Em models.rs, descrevemos a estrutura 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

Agora, vamos para schema.rs. Aqui, definimos os objetos GraphQL e as consultas:

\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

Observe o uso de #[derive(SimpleObject)] — esta é uma macro do async-graphql que gera automaticamente o tipo GraphQL.

\n\n

Resolvers: lógica de negócio

\n

No arquivo resolvers.rs, implementamos a função de obtenção de dados. Para simplificar, usaremos uma lista estática:

\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

Em um projeto real, aqui poderia haver uma consulta ao banco de dados ou a uma API externa.

\n\n

Montagem do servidor com Actix-web

\n

Agora, o mais importante: juntar tudo no 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