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界面。