使用Rust构建GraphQL API:创建Web服务的逐步教程

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程
以下是翻译后的HTML内容:

使用Rust构建GraphQL API:逐步教程



GraphQL是一种API查询语言,允许客户端仅获取所需数据。而Rust以高性能和内存安全著称。在本教程中,我们将使用Juniper和Actix-web库,在Rust中创建一个完整的GraphQL API。您将学习如何配置服务器、定义模式、实现查询和变更,以及测试API。



本文适合熟悉Rust基础和Web开发的开发者。我们将专注于实践实现,避免过多的理论内容。



项目设置与依赖安装



首先,创建一个新的Rust项目:



cargo new rust-graphql-apicd rust-graphql-api


在Cargo.toml文件中添加必要的依赖:



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


其中actix-web是一个Web框架,juniper是用于GraphQL的库。juniper_actix提供了它们之间的集成。



创建基本的GraphQL模式



现在,定义一个简单的数据模型和模式。以用户和帖子的管理系统为例。



创建文件src/schema.rs:



use juniper::{GraphQLObject, GraphQLInputObject, RootNode};

#[derive(GraphQLObject)]#[graphql(description = "系统用户")]pub struct User { pub id: i32, pub name: String, pub email: String,}

#[derive(GraphQLInputObject)]#[graphql(description = "创建用户的输入数据")]pub struct NewUser { pub name: String, pub email: String,}

#[derive(GraphQLObject)]#[graphql(description = "用户帖子")]pub struct Post { pub id: i32, pub title: String, pub body: String, pub author_id: i32,}

pub struct QueryRoot;

#[juniper::object]impl QueryRoot { fn users() -> Vec<User> { vec![ User { id: 1, name: "阿列克谢".into(), email: "alex@example.com".into() }, User { id: 2, name: "玛丽亚".into(), email: "maria@example.com".into() }, ] }

fn posts() -> Vec<Post> { vec![ Post { id: 1, title: "第一篇帖子".into(), body: "帖子内容".into(), author_id: 1 }, ] }}

pub struct MutationRoot;

#[juniper::object]impl MutationRoot { fn create_user(new_user: NewUser) -> User { User { id: 3, name: new_user.name, email: new_user.email, } }}

pub type Schema = RootNode<'static, QueryRoot, MutationRoot>;


我们定义了两个根对象:QueryRoot用于查询(获取数据),MutationRoot用于变更(修改数据)。#[derive(GraphQLObject)]会自动从Rust结构体生成GraphQL类型。



配置Web服务器并与Actix-web集成



现在,创建主文件src/main.rs来启动服务器:



mod schema;

use actix_web::{web, App, HttpServer, HttpResponse, middleware};use juniper_actix::{graphql_handler, playground_handler};use std::sync::Arc;

use crate::schema::Schema;

async fn graphql_route( req: actix_web::HttpRequest, payload: actix_web::web::Payload, schema: web::Data<Arc<Schema>>,) -> actix_web::Result<HttpResponse> { let context = (); graphql_handler(&schema, &context, req, payload).await}

async fn playground_route() -> actix_web::Result<HttpResponse> { playground_handler("/graphql", None).await}

#[actix_web::main]async fn main() -> std::io::Result<()> { let

博客

书籍推荐