Rust GraphQL服务库juniper_axum的使用:集成Juniper与Axum实现高性能GraphQL API开发

Rust GraphQL服务库juniper_axum的使用:集成Juniper与Axum实现高性能GraphQL API开发

juniper_axum crate

axum web服务器与juniper(Rust的GraphQL实现)的集成库。

文档

获取文档,包括指南和示例。

示例

以下是使用juniper_axum创建GraphQL服务器的完整示例:

use axum::{
    routing::get,
    Router,
};
use juniper::{
    graphql_object, EmptyMutation, EmptySubscription, RootNode,
};
use juniper_axum::{graphiql, graphql, playground};
use std::sync::Arc;

// 定义GraphQL上下文
struct Context;
impl juniper::Context for Context {}

// 定义查询类型
struct Query;

// 添加GraphQL解析器
#[graphql_object(context = Context)]
impl Query {
    fn hello(&self) -> &str {
        "Hello, world!"
    }
}

// 定义GraphQL Schema
type Schema = RootNode<'static, Query, EmptyMutation<Context>, EmptySubscription<Context>>;

#[tokio::main]
async fn main() {
    // 创建Schema实例
    let schema = Arc::new(Schema::new(
        Query,
        EmptyMutation::<Context>::new(),
        EmptySubscription::<Context>::new(),
    ));

    // 创建路由
    let app = Router::new()
        .route("/", get(graphiql("/graphql", None)).post(graphql))
        .route("/graphql", get(graphiql("/graphql", None)).post(graphql))
        .route("/playground", get(playground("/graphql", None)))
        .with_state(schema);

    // 启动服务器
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await
        .unwrap();
    println!("GraphQL server running at http://localhost:3000");
    axum::serve(listener, app).await.unwrap();
}

完整示例demo

以下是一个更完整的GraphQL API示例,包含查询和变更操作:

use axum::{
    extract::State,
    routing::{get, post},
    Router,
};
use juniper::{
    graphql_object, graphql_subscription, EmptyMutation, EmptySubscription, FieldError, RootNode,
    GraphQLInputObject, GraphQLObject,
};
use juniper_axum::{graphiql, graphql, playground};
use std::sync::Arc;

// 定义用户数据结构
#[derive(GraphQLObject)]
struct User {
    id: i32,
    name: String,
    email: String,
}

// 定义用户输入
#[derive(GraphQLInputObject)]
struct NewUser {
    name: String,
    email: String,
}

// 定义GraphQL上下文
struct Database {
    users: Vec<User>,
}
impl juniper::Context for Database {}

// 定义查询类型
struct Query;

#[graphql_object(context = Database)]
impl Query {
    // 获取所有用户
    async fn users(context: &Database) -> Vec<User> {
        context.users.clone()
    }

    // 通过ID获取用户
    async fn user(context: &Database, id: i32) -> Option<User> {
        context.users.iter().find(|user| user.id == id).cloned()
    }
}

// 定义变更类型
struct Mutation;

#[graphql_object(context = Database)]
impl Mutation {
    // 创建新用户
    async fn create_user(context: &Database, new_user: NewUser) -> Result<User, FieldError> {
        let user = User {
            id: context.users.len() as i32 + 1,
            name: new_user.name,
            email: new_user.email,
        };
        // 在实际应用中这里应该将用户保存到数据库
        Ok(user)
    }
}

// 定义GraphQL Schema
type Schema = RootNode<'static, Query, Mutation, EmptySubscription<Database>>;

#[tokio::main]
async fn main() {
    // 初始化数据库
    let db = Arc::new(Database {
        users: vec![
            User {
                id: 1,
                name: "Alice".to_string(),
                email: "alice@example.com".to_string(),
            },
            User {
                id: 2,
                name: "Bob".to_string(),
                email: "bob@example.com".to_string(),
            },
        ],
    });

    // 创建Schema实例
    let schema = Arc::new(Schema::new(
        Query,
        Mutation,
        EmptySubscription::<Database>::new(),
    ));

    // 创建路由
    let app = Router::new()
        .route("/", get(graphiql("/graphql", None)).post(graphql))
        .route("/graphql", get(graphiql("/graphql", None)).post(graphql))
        .route("/playground", get(playground("/graphql", None)))
        .with_state(schema);

    // 启动服务器
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000")
        .await
        .unwrap();
    println!("GraphQL server running at http://localhost:3000");
    axum::serve(listener, app).await.unwrap();
}

安装

在项目目录中运行以下Cargo命令:

cargo add juniper_axum

或者在Cargo.toml中添加以下行:

juniper_axum = "0.2.0"

许可证

此项目采用BSD 2-Clause License许可证。


1 回复

Rust GraphQL服务库juniper_axum的使用指南

介绍

juniper_axum是一个将Juniper GraphQL库与Axum Web框架集成的Rust库,用于构建高性能的GraphQL API服务。它结合了Juniper强大的GraphQL实现和Axum的高效异步处理能力。

主要特点

  • 无缝集成Juniper和Axum
  • 支持GraphQL查询和变更操作
  • 内置异步支持
  • 类型安全
  • 易于与现有Axum应用集成

完整示例代码

use axum::{
    routing::get,
    Router,
    Extension,
};
use juniper::{GraphQLObject, GraphQLInputObject, RootNode};
use juniper_axum::{graphiql, graphql, playground};

// 定义GraphQL对象类型
#[derive(GraphQLObject)]
struct User {
    id: String,
    name: String,
    email: String,
}

// 定义GraphQL输入类型
#[derive(GraphQLInputObject)]
struct NewUser {
    name: String,
    email: String,
}

// 查询根类型
struct Query;

#[juniper::graphql_object]
impl Query {
    async fn users() -> Vec<User> {
        // 模拟从数据库获取数据
        vec![
            User {
                id: "1".to_string(),
                name: "Alice".to_string(),
                email: "alice@example.com".to_string(),
            }
        ]
    }
}

// 变更根类型
struct Mutation;

#[juniper::graphql_object]
impl Mutation {
    async fn create_user(new_user: NewUser) -> User {
        // 模拟创建用户并返回
        User {
            id: "2".to_string(),
            name: new_user.name,
            email: new_user.email,
        }
    }
}

// 定义Schema类型
type Schema = RootNode<'static, Query, Mutation>;

// 创建Schema实例
fn create_schema() -> Schema {
    Schema::new(Query, Mutation)
}

// 设置Axum路由
async fn app() -> Router {
    let schema = std::sync::Arc::new(create_schema());
    
    Router::new()
        // GraphQL playground界面
        .route("/graphql", get(playground("/graphql", None)).post(graphql(schema)))
        // GraphiQL界面
        .route("/graphiql", get(graphiql("/graphql", None)))
        // 共享Schema
        .layer(Extension(schema))
}

// 主函数
#[tokio::main]
async fn main() {
    let app = app().await;
    
    // 绑定3000端口
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    println!("GraphQL server running on http://localhost:3000/graphql");
    println!("GraphiQL UI running on http://localhost:3000/graphiql");
    
    // 启动服务器
    axum::serve(listener, app).await.unwrap();
}

示例查询

GraphQL查询示例

query {
  users {
    id
    name
    email
  }
}

GraphQL变更示例

mutation {
  createUser(newUser: {name: "Bob", email: "bob@example.com"}) {
    id
    name
    email
  }
}

通过这个完整示例,你可以快速搭建一个功能完备的GraphQL API服务,包含查询和变更操作,以及开发用的GraphiQL界面。

回到顶部