如何使用Rust构建强大的GraphQL API
本指南将详细介绍如何使用Rust构建一个强大的GraphQL API。从创建HTTP服务器到添加GraphQL支持,再到实现一个小型API,您将逐步学习如何完成这些任务。此外,您还将了解如何通过添加跟踪和度量功能来优化服务的可观察性,并最终将其容器化以便部署。
关于Rust和GraphQL
GraphQL简介
GraphQL是一种开源的数据查询和操作语言,同时也是一种运行时,用于根据客户端的查询返回数据。它最初由Facebook于2012年开发,并于2016年公开发布。相比传统的REST API,GraphQL为客户端提供了更大的灵活性。客户端可以明确指定所需的数据,避免了返回冗余字段的问题。
如今,Netflix、Spotify、Shopify等许多知名公司都在使用GraphQL来构建API。特别是联邦GraphQL API(由多个微服务组成的大型超图)极大地提升了灵活性,使团队能够独立开发,同时为客户端提供了统一的接口。
Rust简介
Rust是一种静态类型的系统编程语言,能够编译为高效的机器代码。它的运行速度与C和C++相当,同时提供了现代化的语言特性和强大的生态系统。Rust以其安全性和性能著称,是构建高效系统的理想选择。
准备工作
在开始之前,请确保您已安装Rust工具链(推荐使用 rustup)。此外,建议使用Rust版本 1.72.0 或更高版本。您可以通过以下命令检查当前安装的Rust版本:
rustc --version
设置项目
- 打开终端,导航到您希望存放项目的目录。
- 创建一个新文件夹并进入该文件夹:
mkdir rust_graphql_api && cd rust_graphql_api - 使用Cargo创建一个新的Rust项目:
cargo new --bin rust_graphql_api cd rust_graphql_api
固定Rust版本
为确保项目的稳定性,创建一个名为 rust-toolchain.toml 的文件,并添加以下内容:
[toolchain]
channel = "1.72.0"
components = ["rustfmt", "clippy"]
此文件将固定Rust版本并启用代码格式化工具 rustfmt 和代码检查工具 clippy。
配置格式化和Lint规则
创建 .rustfmt.toml 文件并添加以下内容:
edition = "2021"
newline_style = "Unix"
同时,为 clippy 创建配置文件 .clippy.toml:
cognitive-complexity-threshold = 30
完成后,您可以使用以下命令格式化代码并检查代码质量:
cargo fmt --all
cargo clippy --all-targets --all-features
创建Web服务器
在 Cargo.toml 中添加以下依赖项:
[dependencies]
axum = "0.6"
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
然后,在 src/main.rs 中实现一个基本的HTTP服务器:
use axum::{routing::get, Router};
use std::net::SocketAddr;
#[tokio::main]
async fn main() {
let app = Router::new().route("/health", get(health_check));
let addr = SocketAddr::from(([127, 0, 0, 1], 8000));
println!("Listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn health_check() -> &'static str {
"OK"
}
运行以下命令启动服务器:
cargo run
打开浏览器访问 http://localhost:8000/health,您将看到返回的 OK 响应。
添加GraphQL支持
在 Cargo.toml 中添加以下依赖项:
[dependencies]
async-graphql = "5.0"
async-graphql-axum = "5.0"
定义GraphQL模式
在 src/model/mod.rs 中添加以下代码:
use async_graphql::{Context, Object};
pub struct QueryRoot;
#[Object]
impl QueryRoot {
async fn hello(&self, _ctx: &Context) -> &str {
"Hello, GraphQL!"
}
}
配置GraphQL路由
在 src/routes/mod.rs 中添加以下代码:
use async_graphql::{Schema, EmptyMutation, EmptySubscription};
use async_graphql_axum::{GraphQLRequest, GraphQLResponse};
use axum::response::Html;
use crate::model::QueryRoot;
pub async fn graphql_handler(schema: Schema, req: GraphQLRequest) -> GraphQLResponse {
schema.execute(req.into_inner()).await.into()
}
pub async fn graphql_playground() -> Html {
Html(async_graphql::http::playground_source("/graphql"))
}
在 src/main.rs 中注册GraphQL路由:
use async_graphql::{Schema, EmptyMutation, EmptySubscription};
use axum::{routing::get, Router};
use crate::routes::{graphql_handler, graphql_playground};
use crate::model::QueryRoot;
#[tokio::main]
async fn main() {
let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription).finish();
let app = Router::new()
.route("/graphql", get(graphql_playground).post(graphql_handler))
.layer(async_graphql::extensions::ApolloTracing);
let addr = SocketAddr::from(([127, 0, 0, 1], 8000));
println!("GraphQL Playground: http://{}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
启动服务后,访问 http://localhost:8000/graphql,即可使用GraphQL Playground测试查询。
添加指标和跟踪
集成Prometheus指标
在 Cargo.toml 中添加以下依赖项:
[dependencies]
metrics = "0.17"
metrics-exporter-prometheus = "0.17"
在 src/observability/metrics.rs 中实现Prometheus指标记录器:
use metrics_exporter_prometheus::PrometheusBuilder;
pub fn setup_metrics() {
PrometheusBuilder::new()
.install()
.expect("failed to install Prometheus recorder");
}
在 main.rs 中调用 setup_metrics 并添加 /metrics 路由。
添加OpenTelemetry跟踪
在 Cargo.toml 中添加以下依赖项:
[dependencies]
tracing = "0.1"
tracing-subscriber = "0.3"
opentelemetry = "0.18"
在 src/observability/tracing.rs 中配置OpenTelemetry:
use opentelemetry::sdk::trace as sdktrace;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::Registry;
pub fn setup_tracing() {
let tracer = sdktrace::Tracer::builder().build();
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
let subscriber = Registry::default().with(telemetry);
tracing::subscriber::set_global_default(subscriber).expect("setting tracing default failed");
}
在 main.rs 中调用 setup_tracing。
容器化服务
创建 .dockerignore 文件:
target
创建 Dockerfile:
FROM rust:1.72 as builder
WORKDIR /usr/src/app
COPY . .
RUN cargo build --release
FROM debian:buster-slim
COPY --from=builder /usr/src/app/target/release/rust_graphql_api /usr/local/bin/
CMD ["rust_graphql_api"]
构建并运行容器:
docker build -t rust_graphql_api .
docker run -p 8000:8000 rust_graphql_api
总结
通过本指南,您已经成功完成以下任务:
- 使用Rust创建了一个基本的GraphQL API。
- 添加了Prometheus指标和OpenTelemetry跟踪。
- 将服务容器化,方便部署。
恭喜您完成了这一切!继续探索Rust和GraphQL的更多可能性吧!
原文链接: https://oliverjumpertz.com/blog/how-to-build-a-powerful-graphql-api-with-rust/
热门API
- 1. AI文本生成
- 2. AI图片生成_文生图
- 3. AI图片生成_图生图
- 4. AI图像编辑
- 5. AI视频生成_文生视频
- 6. AI视频生成_图生视频
- 7. AI语音合成_文生语音
- 8. AI文本生成(中国)
最新文章
- Python应用 | 网易云音乐热评API获取教程
- 22条API设计的最佳实践
- 低成本航空公司的分销革命:如何通过API实现高效连接与服务
- 实时聊天搭建服务:如何打造令人着迷的社交媒体体验?
- 简化API缩写:应用程序编程接口终极指南
- Mono Creditworthy API 集成指南|实时评估用户信用状况
- Gcore 收购 StackPath WAAP,增强全球边缘Web应用与API安全能力
- 免费IPv6地址查询接口推荐
- 什么是Unified API?基于未来集成的访问
- 使用JWT和Lambda授权器保护AWS API网关:Clerk实践指南
- 宠物领养服务:如何帮流浪毛孩找到温馨的新家?
- Python调用IP地址归属地查询API教程