GraphQL API com Rust: tutorial passo a passo para criar um backend rápido

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
```html

Introdução ao GraphQL API em Rust



O desenvolvimento web moderno exige alta performance e flexibilidade ao trabalhar com dados. Rust é uma linguagem de programação de sistemas, conhecida por sua velocidade e segurança de memória, enquanto GraphQL é uma poderosa linguagem de consulta que permite aos clientes obter apenas os dados necessários. A combinação dessas tecnologias resulta em APIs incrivelmente rápidas e convenientes.



Neste tutorial, criaremos uma API GraphQL completa em Rust usando os populares crates Juniper (para implementação do GraphQL) e Actix-web (para o servidor HTTP). Você aprenderá como configurar o projeto, definir o schema, implementar resolvers e processar requisições.



O artigo é voltado para desenvolvedores que já conhecem os fundamentos do Rust e os conceitos básicos de APIs web. Usaremos a edição Rust 2021 e as versões estáveis mais recentes das dependências.



Passo 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


Em seguida, abra o arquivo Cargo.toml e adicione as seguintes dependências:



[dependencies]actix-web = "4"actix-rt = "2"juniper = "0.16"serde = { version = "1.0", features = ["derive"] }tokio = { version = "1", features = ["full"] }


  • actix-web — framework web assíncrono para Rust.
  • juniper — biblioteca para implementar GraphQL em Rust.
  • serde — para serialização/desserialização de dados.
  • tokio — runtime assíncrono, necessário para o Actix.


Após atualizar as dependências, execute cargo build para garantir que tudo seja instalado corretamente.



Passo 2: Definição do modelo de dados e do schema GraphQL



Como exemplo, criaremos um modelo simples "Livro" com os campos: id, título, autor e ano de publicação. Crie o arquivo src/models.rs:



use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]pub struct Book { pub id: i32, pub title: String, pub author: String, pub year: i32,}


Agora, vamos definir o schema GraphQL. Crie o arquivo src/graphql.rs:



use juniper::{FieldResult, GraphQLObject, GraphQLInputObject, RootNode};use crate::models::Book;

// Tipo GraphQL para livro (saída)#[derive(GraphQLObject)]#[graphql(description = "Livro")]pub struct BookGQL { pub id: i32, pub title: String, pub author: String, pub year: i32,}

// Tipo de entrada para criar um livro#[derive(GraphQLInputObject)]#[graphql(description = "Dados de entrada para um novo livro")]pub struct NewBook { pub title: String, pub author: String, pub year: i32,}

// "Banco de dados" em memóriause std::sync::Mutex;lazy_static::lazy_static! { static ref BOOKS: Mutex<Vec<Book>> = Mutex::new(vec![ Book { id: 1, title: "Rust em Ação".to_string(), author: "Tim McNamara".to_string(), year: 2021 }, Book { id: 2, title: "Programação em Rust".to_string(), author: "Jim Blandy".to_string(), year: 2020 }, ]);}

// Consulta raiz (Query)pub struct QueryRoot;

#[juniper::object]impl QueryRoot { fn books() -> FieldResult<Vec<BookGQL>> { let books = BOOKS.lock().unwrap(); Ok(books.iter().map(|b| BookGQL { id: b.id, title: b.title.clone(), author: b.author.clone(), year: b.year, }).collect()) }

fn book(id: i32) -> FieldResult<BookGQL> { let books = BOOKS.lock().unwrap(); let book = books.iter().find(|b| b.id == id) .ok_or_else(|| juniper::FieldError::new("Livro não encontrado", graphql_value!({"code": "NOT_FOUND"})))?; Ok(BookGQL { id: book.id, ```

Blogs

Book Recommendations