關于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的更多可能性吧!


原文鏈接: https://oliverjumpertz.com/blog/how-to-build-a-powerful-graphql-api-with-rust/

上一篇:

使用 Rails 構建 RESTful API

下一篇:

使用 python 和 flask 構建 restful api
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費