所有文章 > API开发 > 如何使用Rust构建强大的GraphQL API
如何使用Rust构建强大的GraphQL API

如何使用Rust构建强大的GraphQL API

本指南将详细介绍如何使用Rust构建一个强大的GraphQL API。从创建HTTP服务器到添加GraphQL支持,再到实现一个小型API,您将逐步学习如何完成这些任务。此外,您还将了解如何通过添加跟踪和度量功能来优化服务的可观察性,并最终将其容器化以便部署。


关于Rust和GraphQL

GraphQL简介

GraphQL是一种开源的数据查询和操作语言,同时也是一种运行时,用于根据客户端的查询返回数据。它最初由Facebook于2012年开发,并于2016年公开发布。相比传统的REST API,GraphQL为客户端提供了更大的灵活性。客户端可以明确指定所需的数据,避免了返回冗余字段的问题。

如今,Netflix、SpotifyShopify等许多知名公司都在使用GraphQL来构建API。特别是联邦GraphQL API(由多个微服务组成的大型超图)极大地提升了灵活性,使团队能够独立开发,同时为客户端提供了统一的接口。

Rust简介

Rust是一种静态类型的系统编程语言,能够编译为高效的机器代码。它的运行速度与C和C++相当,同时提供了现代化的语言特性和强大的生态系统。Rust以其安全性和性能著称,是构建高效系统的理想选择。


准备工作

在开始之前,请确保您已安装Rust工具链(推荐使用 rustup)。此外,建议使用Rust版本 1.72.0 或更高版本。您可以通过以下命令检查当前安装的Rust版本:

rustc --version

设置项目

  1. 打开终端,导航到您希望存放项目的目录。
  2. 创建一个新文件夹并进入该文件夹:
    mkdir rust_graphql_api && cd rust_graphql_api
  3. 使用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文章!

我们有何不同?

API服务商零注册

多API并行试用

数据驱动选型,提升决策效率

查看全部API→
🔥

热门场景实测,选对API

#AI文本生成大模型API

对比大模型API的内容创意新颖性、情感共鸣力、商业转化潜力

25个渠道
一键对比试用API 限时免费

#AI深度推理大模型API

对比大模型API的逻辑推理准确性、分析深度、可视化建议合理性

10个渠道
一键对比试用API 限时免费