rust语言服务器引擎,快速入门 - Juniper - Rust 语言的 GraphQL 服务器

quickstart.md

commit 29025e6cae4a249fa56017dcf16b95ee4e89363e

简要介绍 Juniper 中的概念。

!文件名 Cargo.toml

[dependencies]

juniper = "^0.13.1"

要将 Rust 语言的 enums 和 structs 暴露为 GraphQL,仅需向其增加一个自定义派生属性。Juniper 支持将 Rust 语言基本类型轻而易举地映射到 GraphQL 特性,诸如:Option、Vec、Box、String、f64 和 i32、引用和切片(slice).

对于更高级的映射,Juniper 提供了多种宏(macro)来将 Rust 类型映射到 GraphQL 模式。过程宏对象是最重要的宏对象之一,其用于声明解析器对象,你将使用解析器对象来 查询(Query) 和 变更(Mutation) 根(roots)。

use juniper::{FieldResult};

struct DatabasePool;impl DatabasePool {fn get_connection(&self) -> FieldResult { Ok(DatabasePool) }fn find_human(&self, _id: &str) -> FieldResult { Err("")? }fn insert_human(&self, _human: &NewHuman) -> FieldResult { Err("")? }}

#[derive(juniper::GraphQLEnum)]

enum Episode {

NewHope,

Empire,

Jedi,

}

#[derive(juniper::GraphQLObject)]

#[graphql(description="星球大战中的类人生物")]

struct Human {

id: String,

name: String,

appears_in: Vec,

home_planet: String,

}

// 另一个用于映射 GraphQL 输入对象的自定义派生。

#[derive(juniper::GraphQLInputObject)]

#[graphql(description="星球大战中的类人生物")]

struct NewHuman {

name: String,

appears_in: Vec,

home_planet: String,

}

// 使用宏对象创建带有解析器的根查询和根变更。

// 对象可以拥有类似数据库池一样的允许访问共享状态的上下文。

struct Context {

// 这里使用真实数据池

pool: DatabasePool,

}

// 要让 Juniper 使用上下文,必须实现标注特性(trait)

impl juniper::Context for Context {}

struct Query;

#[juniper::object(

// 指定对象的上下文类型。

// 需要访问上下文的每种类型都需如此。

Context = Context,

)]

impl Query {

fn apiVersion() -> &str {

"1.0"

}

// 解析器的参数可以是简单类型,也可以是输入对象。

// 为了访问上下文,我们指定了一个引用上下文类型的参数。

// Juniper 会自动注入正确的上下文。

fn human(context: &Context, id: String) -> FieldResult {

// 获取数据库连接

let connection = context.pool.get_connection()?;

// 执行查询

// 注意 `?` 的用法,进行错误传播。

// 译者注:上一章“特点”中提到,Juniper 默认构建非空类型

let human = connection.find_human(&id)?;

// 返回结果集

Ok(human)

}

}

// 下面对变更类型做同样的事情

struct Mutation;

#[juniper::object(

Context = Context,

)]

impl Mutation {

fn createHuman(context: &Context, new_human: NewHuman) -> FieldResult {

let db = executor.context().pool.get_connection()?;

let human: Human = db.insert_human(&new_human)?;

Ok(human)

}

}

// 根模式由查询和变更组成,故查询请求可以执行于 RootNode。

type Schema = juniper::RootNode;

fn main() {let _ = Schema::new(Query, Mutation{});}

现在,我们有了一个非常简单,但模式功能齐全的 GraphQL服务器。

要让此模式在服务器端起作用,查阅各类服务器集成指南。

也可以直接调用执行器(executor)来获取查询结果集:

可以直接调用 juniper::execute 来运行 GraphQL 查询:

// 由于宏(macro)不可访问,如下代码仅 Rust-2018 版需要#[macro_use] extern crate juniper;use juniper::{FieldResult, Variables, EmptyMutation};

#[derive(juniper::GraphQLEnum, Clone, Copy)]

enum Episode {

NewHope,

Empire,

Jedi,

}

// 上下文(context)数据

struct Ctx(Episode);

impl juniper::Context for Ctx {}

struct Query;

#[juniper::object(

Context = Ctx,

)]

impl Query {

fn favoriteEpisode(context: &Ctx) -> FieldResult {

Ok(context.0)

}

}

// 根模式由查询和变更组成,故查询请求可以执行于 RootNode。

type Schema = juniper::RootNode>;

fn main() {

// 创建上下文对象

let ctx = Ctx(Episode::NewHope);

// 运行执行器

let (res, _errors) = juniper::execute(

"query { favoriteEpisode }",

None,

&Schema::new(Query, EmptyMutation::new()),

&Variables::new(),

&ctx,

).unwrap();

// 确保查询结果值匹配

assert_eq!(

res,

graphql_value!({

"favoriteEpisode": "NEW_HOPE",

})

);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值