Rust高性能GraphQL路由库apollo-router的使用,Apollo Router为Rust开发者提供灵活可扩展的GraphQL查询分发与缓存功能
Apollo Router Core
Apollo Router Core 是一个用 Rust 编写的高性能图形路由器,用于运行使用 Apollo Federation 2 的联邦超级图。它经过充分测试,定期进行基准测试,包含 Apollo Gateway 的主要功能,并服务于生产规模的工作负载。
使用 Apollo Router Core 作为库
大多数 Apollo Router Core 功能可以通过 YAML 配置定义,许多自定义可以通过 Rhai 脚本编写,这些脚本适用于已发布的 router 二进制文件,不需要编译。
如果您更喜欢用 Rust 编写自定义或需要更高级的自定义,可以了解如何将 apollo-router
用作 Rust 库。我们还在 crate 文档上发布 Rust 特定的文档。
此版本的 apollo-router
的最低支持 Rust 版本 (MSRV) 是 1.87.0。
安装
全局安装
cargo install apollo-router
运行上述命令将全局安装 router
和 snapshot
二进制文件。
作为库安装
在项目目录中运行以下 Cargo 命令:
cargo add apollo-router
或者将以下行添加到您的 Cargo.toml:
apollo-router = "2.5.0"
完整示例
以下是一个使用 Apollo Router 的完整示例:
use apollo_router::{Router, Schema};
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 加载 GraphQL 模式
let schema = Schema::parse(include_str!("schema.graphql"))?;
// 创建路由器实例
let router = Router::builder()
.schema(schema)
.build()?;
// 启动服务器
router.serve("127.0.0.1:4000".parse()?).await?;
Ok(())
}
# schema.graphql
type Query {
hello: String
}
此示例展示了如何:
- 加载 GraphQL 模式
- 创建一个路由器实例
- 启动服务器监听端口 4000
您可以通过添加 YAML 配置文件或 Rhai 脚本来自定义路由器的行为,或者使用原生 Rust 扩展来实现更高级的功能。
更完整示例
下面是一个更完整的 Apollo Router 使用示例,包含自定义插件:
use apollo_router::{Router, Schema, plugins::Plugin, Response};
use std::error::Error;
use tokio::sync::Mutex;
use std::sync::Arc;
// 自定义插件
#[derive(Default)]
struct MyPlugin {
request_count: Arc<Mutex<u32>>,
}
#[async_trait::async_trait]
impl Plugin for MyPlugin {
async fn on_request(&self, _request: &apollo_router::Request) -> Result<(), Box<dyn Error>> {
let mut count = self.request_count.lock().await;
*count += 1;
println!("Request count: {}", count);
Ok(())
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 加载 GraphQL 模式
let schema = Schema::parse(include_str!("schema.graphql"))?;
// 创建路由器实例并添加自定义插件
let router = Router::builder()
.schema(schema)
.plugin(MyPlugin::default())
.build()?;
// 启动服务器
println!("Server running on http://localhost:4000");
router.serve("127.0.0.1:4000".parse()?).await?;
Ok(())
}
# schema.graphql
type Query {
hello: String
users: [User]
}
type User {
id: ID!
name: String
email: String
}
这个更完整的示例展示了:
- 如何定义一个自定义插件
- 如何在插件中跟踪请求计数
- 如何将插件添加到路由器
- 扩展了 GraphQL 模式
- 添加了服务器启动日志
您可以根据需要进一步扩展此示例,例如添加更多自定义插件或实现更复杂的业务逻辑。
Rust高性能GraphQL路由库apollo-router使用指南
介绍
Apollo Router是一个用Rust编写的高性能GraphQL路由库,专为构建灵活、可扩展的GraphQL网关而设计。它为Rust开发者提供了强大的查询分发和缓存功能,能够高效地处理GraphQL请求。
主要特性:
- 高性能:基于Rust构建,提供极低延迟的GraphQL请求处理
- 可扩展架构:支持自定义插件和中间件
- 智能查询分发:可路由到不同的后端服务
- 内置缓存:减少重复计算和网络请求
- 联邦支持:兼容Apollo Federation规范
安装方法
在Cargo.toml中添加依赖:
[dependencies]
apollo-router = "1.0"
tokio = { version = "1.0", features = ["full"] }
基本使用方法
1. 创建基本路由
use apollo_router::{Router, Schema};
use async_graphql::{EmptyMutation, EmptySubscription, Object, Schema as GraphQLSchema};
struct Query;
#[Object]
impl Query {
async fn hello(&self) -> String {
"Hello, Apollo Router!".to_string()
}
}
#[tokio::main]
async fn main() {
// 创建GraphQL schema
let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();
// 创建并启动路由器
let router = Router::builder()
.schema(schema)
.build()
.unwrap();
router.run().await.unwrap();
}
2. 配置路由端点
use apollo_router::{Router, Schema, Endpoint};
// ...之前的Query定义...
#[tokio::main]
async fn main() {
let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();
let router = Router::builder()
.schema(schema)
.endpoint(Endpoint::from("/graphql"))
.endpoint(Endpoint::from("/api").disable_graphql_playground())
.build()
.unwrap();
router.run().await.unwrap();
}
3. 添加缓存层
use apollo_router::{Router, Schema, cache::InMemoryCache};
// ...之前的Query定义...
#[tokio::main]
async fn main() {
let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();
let cache = InMemoryCache::new();
let router = Router::builder()
.schema(schema)
.cache(cache)
.build
.unwrap();
router.run().await.unwrap();
}
高级功能
1. 自定义插件
use apollo_router::{Router, Schema, Plugin, Request, Response};
use std::task::{Context, Poll};
use tower::Service;
struct LoggingPlugin;
impl Plugin for LoggingPlugin {
fn name(&self) -> &'static str {
"logging-plugin"
}
}
impl<S> Service<Request> for LoggingPlugin
where
S: Service<Request, Response = Response>,
{
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, req: Request, next: S) -> Self::Future {
println!("Received request: {:?}", req);
next.call(req)
}
}
#[tokio::main]
async fn main() {
let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();
let router = Router::builder()
.schema(schema)
.plugin(LoggingPlugin)
.build()
.unwrap();
router.run().await.unwrap();
}
2. 联邦服务支持
use apollo_router::{Router, federated::FederatedRouter};
#[tokio::main]
async fn main() {
let router = FederatedRouter::builder()
.subgraph("accounts", "http://localhost:4001/graphql")
.subgraph("reviews", "http://localhost:4002/graphql")
.subgraph("products", "http://localhost:4003/graphql")
.build()
.unwrap();
router.run().await.unwrap();
}
性能调优
use apollo_router::{Router, Schema, cache::InMemoryCache};
#[tokio::main]
async fn main() {
let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();
let cache = InMemoryCache::with_capacity(1024); // 设置缓存容量
let router = Router::builder()
.schema(schema)
.cache(cache)
.query_plan_cache_size(512) // 查询计划缓存大小
.worker_threads(4) // 工作线程数
.build()
.unwrap();
router.run().await.unwrap();
}
完整示例
下面是一个结合了基本路由、缓存和自定义插件的完整示例:
use apollo_router::{Router, Schema, Plugin, Request, Response, cache::InMemoryCache};
use async_graphql::{EmptyMutation, EmptySubscription, Object};
use std::task::{Context, Poll};
use tower::Service;
// 定义查询结构体
struct Query;
#[Object]
impl Query {
async fn version(&self) -> String {
"1.0.0".to_string()
}
async fn server_info(&self) -> String {
"Apollo Router Server".to_string()
}
}
// 自定义日志插件
struct RequestLogger;
impl Plugin for RequestLogger {
fn name(&self) -> &'static str {
"request-logger"
}
}
impl<S> Service<Request> for RequestLogger
where
S: Service<Request, Response = Response>,
{
type Response = S::Response;
type Error = S::Error;
type Future = S::Future;
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}
fn call(&mut self, req: Request, next: S) -> Self::Future {
println!("[RequestLogger] Incoming request to path: {}", req.uri().path());
next.call(req)
}
}
#[tokio::main]
async fn main() {
// 创建GraphQL schema
let schema = Schema::build(Query, EmptyMutation, EmptySubscription).finish();
// 创建内存缓存
let cache = InMemoryCache::with_capacity(512);
// 构建路由器
let router = Router::builder()
.schema(schema)
.cache(cache)
.plugin(RequestLogger)
.endpoint("/graphql")
.worker_threads(2)
.build()
.unwrap();
println!("Server running at http://localhost:4000/graphql");
router.run().await.unwrap();
}
总结
Apollo Router为Rust开发者提供了一个高性能、可扩展的GraphQL路由解决方案。通过简单的API,开发者可以快速构建GraphQL网关,并利用其强大的缓存、插件和联邦功能来优化GraphQL服务的性能和可维护性。