1. 缘起

Facebook 的移动应用从 2012 年就开始使用 GraphQL。GraphQL 规范于 2015 年开源,现已经在多种环境下可用,并被各种体量的团队所使用。

这个链接可以看到更多的GraphQL使用者。

2. GraphQL是什么

英文官网:GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data.

中文官网:GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。

个人理解:GraphQL利用了传统的SQL查询,并且以restful api的形式返回数据。

举个栗子:

传统的Restful api查询,你要查询一个用户的头像信息,不需要别的信息,那么就是需要利用Http发送给服务区user_id,然后服务器返回给你这个用户的所有信息,比如邮箱、昵称、电话、头像等信息。

这样以来,如果返回的数据过大的话,可能会因为网络的各种问题导致延迟。

但是如果像GraphQL,我要查询头像信息,只需要发送

{
hero {
head_url
}
}

那么服务器就只会返回给

{
"hero": {
"head_url": "https://pic.cnblogs.com/face/298986/20150104103009.png"
}
}

嗯,基本就是这样子。仅仅是我的理解,如果不对,麻烦大声告诉我,谢谢。

官网还有一个gif,更加形象。

怎么样,可以的吧。

3. 现存的GraphQL框架

前面说了,GraphQL仅仅就是一个查询语言,如果想用在自己的项目中,你不可能从头开始研究这个语言,然后手撸自己需要的框架。当然,自己写当然没问题。

不过官网提供了一些自己写的或者第三方写的库,包括服务器端和客户端的实现。

详见 ↓

英文:https://graphql.org/code/

中文:https://graphql.cn/code/

这其中不得不赞一下一个第三方的Apollo,牛逼的不要不要的。写了Android、iOS、Javascript,就是不写dot net

.net下不过也有三个:

第一个好像是微软写的,261 stars。。。不过距离上一个版本发版已经有一年了,这一年有了一些新的bug,但是他们之说下一个版本解决,但是需要多久???God knows。

第二个是个人开发者写的,80 stars。但是距离他上一次提交代码是三年前了,so。。。放弃吧先

第三个也是个人开发者写的,26 stars。这个库更新的比较频繁,可以使用。

4. 一个简单的例子

拿微软的例子GraphQL.Client说一下吧

比如就从服务器获取一个pin code

首先自己先写好mutation句子,类似SQL查询的语句。

@"mutation{
generatePinCode
}"

还是有一点点麻烦的地方,就是自己要写查询语句。

像刚才提到的Apollo框架,人家都是给你自动生成的,你气不气。

不过有人在Github提问了,但是微软的人并不打算这么做,可能他们在忙别的事情吧,比如写win10的bug

然后声明一个GraphQL的Client,指定EndPoint地址。

            GraphQLClient client = new GraphQLClient(new GraphQLClientOptions
{
EndPoint = new Uri("http://dev.xxx.com/api/graphql/guest")
});

然后声明GraphQLResponse,来接受服务器返回的消息。

GraphQLResponse response = await client.PostQueryAsync(
@"mutation{
generatePinCode
}"); if(response.Errors == null)
{
var result = response.GetDataFieldAs<string>("generatePinCode");
textBox_Result.Text = textBox_PinCode.Text = result;
}
else
textBox_Result.Text = "Generate Pin Code Failed";

看,就是这么简单的例子。

有人可能好奇,上面的generatePinCode是什么鬼?在哪里出来的。

其实这个是服务器返回来的数据,我们需要从generatePinCode数据区拿数据而已。

说到这里,那么就不得不说一下Altair这个神器了。

在Altair中,发送请求,返回来的数据都是包含在data数据体中的。data里面的generatePinCode才是我们真正想要的。

而通过Altair看出,generatePinCode其实返回了就是一个string类型的字符串。

那么我们只需要GetDataFieldAs函数,直接反序列化即可。

5. 一个有一点点复杂的例子

拿微软的例子GraphQL.Client说一下吧

比如需要做个用户输入用户名密码登录的例子:

那么我们写一个简单的xaml代码:

<TextBox x:Name="textBox_Username" PlaceholderText="user name" BorderThickness="" Margin="0, 20"/>
<TextBox x:Name="textBox_pswd" PlaceholderText="password" BorderThickness=""/>
<Button Content="Login" Margin="0, 20" Tapped="LoginWithUsernamePassword_Tapped"/>

然后自己需要写mutation代码,这里我们就查询user 的所有信息。不过这些信息可以按需自己获取。

@"mutation{
login(email:""" + textBox_Username.Text
+ @""", password:"""+ textBox_pswd.Text
+ @"""){
access_token
token_type
expires_in
user{id
email
nickname
email_verified_at
password
remember_token
mobile
gender
birthdate
type
avatar_uri
avatar_radius_uri
status
auth_privacy
account_type
created_at
updated_at}
}
}";

然后在C#里面响应 LoginWithUsernamePassword_Tapped 时间。

先声明一个GraphQL的Client,指定EndPoint地址。

GraphQLClient client = new GraphQLClient(new GraphQLClientOptions
{
EndPoint = new Uri("http://dev.xxx.com/api/graphql/guest")
});

然后声明GraphQLResponse,来接受服务器返回的消息。

            GraphQLResponse response = await client.PostQueryAsync(query);
if (response.Errors == null)
{ }
else
textBox_Result.Text = "Login With Username Password Failed";

其实看上面的代码,可以看出,和我们之前用Restful Api的方式一模一样。

1. 向指定的url发送请求

2. 获取相应信息

3. 判断返回的消息是否成功,比如status code等。

如果GraphQL返回的Response.Errors是空的话,表示查询成功。接下来要对数据进行反序列化处理,以便接下来我们可以直接使用。

                var result = response.GetDataFieldAs<LoginWithPinCode>("login");
textBox_Result.Text = result.access_token;
image_Head.Source = new BitmapImage(new Uri(result.user.avatar_radius_uri));

到这里,可能会有人好奇"login"是怎么来的?

在Altair中,发送请求,返回来的数据都是包含在data数据体中的。data里面的login才是我们真正想要的。

而LoginWithPinCode类是根据返回的login数据,自己定义的model。

好了,到此。一个完整的利用用户名密码登录的例子就完成了。

C#完整代码:

        private async void LoginWithUsernamePassword_Tapped(object sender, TappedRoutedEventArgs e)
{
client = new GraphQLClient(new GraphQLClientOptions
{
EndPoint = new Uri("http://dev.xxx.com/api/graphql/guest")
}); string query = @"mutation{
login(email:""" + textBox_Username.Text
+ @""", password:"""+ textBox_pswd.Text
+ @"""){
access_token
token_type
expires_in
user{id
email
nickname
email_verified_at
password
remember_token
mobile
gender
birthdate
type
avatar_uri
avatar_radius_uri
status
auth_privacy
account_type
created_at
updated_at}
}
}"; GraphQLResponse response = await client.PostQueryAsync(query); if (response.Errors == null)
{
var result = response.GetDataFieldAs<LoginWithPinCode>("login");
textBox_Result.Text = result.access_token;
image_Head.Source = new BitmapImage(new Uri(result.user.avatar_radius_uri));
}
else
textBox_Result.Text = "Login With Username Password Failed";
}

6. GraphQL使用总结

如果你的项目突然说要换GraphQL方式查询之类的,不要慌。没听过没关系,它也是一个api,通过结合了SQL查询的方式实现。

上面的两个例子都是用微软的库实现的。

如果这三个库都不能满足你的要求,那么就需要用dot net提供的HttpClient来从最底层做起。这样有个好处就是你可以完全按照自己的需要定制。

像前面提到的Apollo框架,它就存在这样那种的限制。Android和iOS开发组,在几个schema文件上花费了好大一段时间,又是合并文件又是命名空间啥的。

不过由于微软的那个库(其实也就是封装了HttpClient,做多了一点处理),封了虽然并没有那么的理想,反而避开了schema这一点。

如果你从HttpClient,当然更不会存在这种问题了。

UWP GraphQL数据查询的实现的更多相关文章

  1. dinoql 使用graphql 语法查询javascript objects

    dinoql 是一个不错的基于graphql 语法查询javascript objects 的工具包,包含以下特性 graphql 语法(很灵活) 安全的访问(当keys 不存在的时候,不会抛出运行时 ...

  2. Django models .all .values .values_list 几种数据查询结果的对比

    Django models .all .values .values_list 几种数据查询结果的对比

  3. MVC实用架构设计(三)——EF-Code First(4):数据查询

    前言 首先对大家表示抱歉,这个系列已经将近一个月没有更新了,相信大家等本篇更新都等得快失望了.实在没办法,由于本人水平有限,写篇博客基本上要大半天的时间,最近实在是抽不出这么长段的空闲时间来写.另外也 ...

  4. 关系数据库SQL之高级数据查询:去重复、组合查询、连接查询、虚拟表

    前言 接上一篇关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询,主要是关系型数据库基本数据查询.包括子查询.分组查询.聚合函数查询.模糊查询,本文是介绍一下关系型数据库几种高级数据查询SQL ...

  5. SharePoint服务器端对象模型 之 使用CAML进展数据查询

    SharePoint服务器端对象模型 之 使用CAML进行数据查询 一.概述 在SharePoint的开发应用中,查询是非常常用的一种手段,根据某些筛选.排序条件,获得某个列表或者某一些列表中相应的列 ...

  6. .NET应用架构设计—面向查询服务的参数化查询设计(分解业务点,单独配置各自的数据查询契约)

    阅读目录: 1.背景介绍 2.对业务功能点进行逻辑划分(如:A.B.C分别三个业务点) 2.1.配置映射关系,对业务点配置查询契约(构造VS插件方便生成查询契约) 2.2.将配置好的映射策略文件放在调 ...

  7. Yii2 数据查询

    转载来自: http://www.yiichina.com/tutorial/95 数据查询 User::find()->all(); 此方法返回所有数据: User::findOne($id) ...

  8. 6、SQL Server 数据查询

    一.使用SELECT检索数据 数据查询是SQL语言的中心内容,SELECT 语句的作用是让数据库服务器根据客户要求检索出所需要的信息资料,并按照规定的格式进行整理,返回给客户端. SELECT 语句的 ...

  9. SQL Server 的表数据简单操作(表数据查询)

    --表数据查询----数据的基本查询-- --数据简单的查询--select * | 字段名[,字段名2, ...] from 数据表名 [where 条件表达式] 例: use 商品管理数据库 go ...

随机推荐

  1. java的Io流机制的学习

    IO流机制 File类的使用 File类的构造方法 File(URI uri) File(String pathname) File(File parent, String child) File(S ...

  2. 快速搭建 SpringCloud 微服务开发环境的脚手架

    本文适合有 SpringBoot 和 SpringCloud 基础知识的人群,跟着本文可使用和快速搭建 SpringCloud 项目. 本文作者:HelloGitHub-秦人 HelloGitHub ...

  3. DDD实战与进阶 - 值对象

    目录 DDD实战与进阶 - 值对象 概述 何为值对象 怎么运用值对象 来看一个例子 值对象的持久化 总结 DDD实战与进阶 - 值对象 概述 作为领域驱动设计战术模式中最为核心的一个部分-值对象.一直 ...

  4. Linux安装redis数据库

    这几天在搞redis数据库,花了好大功夫,才成功安装在Linux上,这里将自己的安装步骤分享出来,同时也做个记录,备忘. 新人一枚,不对之处,请多指教! 首先登陆Linux服务器 Linux里,我习惯 ...

  5. 【高可用架构】借助Envoy工具发布项目到多台服务器

    前言 在上一篇,我们已经成功在开发机上部署了Deploy项目,下面我们继续在开发机上安装Envoy 两台应用服务器的IP 192.168.10.12 192.168.10.18 [高可用架构]系列链接 ...

  6. 04-kubernetes 资源清单定义入门

    目录 资源对象 创建资源的方法 清单帮助命令 创建测试清单 资源的三种创建方式 资源对象 workload:Pod, ReplicaSet, Deployment, StatefulSet, Daem ...

  7. css隐藏页面元素的多种方法

    在平常的样式排版中,我们经常遇到将某个模块隐藏,下面我整理了一下隐藏元素的多种方法以及对比(有的占据空间,有的不占据空间.有的可以点击,有的不能点击.): ( 一 )  display:  none; ...

  8. 使用 Flask 和 Vue.js 来构建全栈单页应用

    在这个教程中,我将向你展示如何将 Vue 的单页面应用和 Flask 后端连接起来. 简单的来说,如果想在 Flask 中使用 Vue 框架是没有什么问题的. 但在实际中存在一个明显的问题就是 Fla ...

  9. 华为云BigData Pro解读: 鲲鹏云容器助力大数据破茧成蝶

    华为云鲲鹏云容器 见证BigData Pro蝶变之旅大数据之路顺应人类科技的进步而诞生,一直顺风顺水,不到20年时间,已渗透到社会生产和人们生活的方方面面,.然而,伴随着信息量的指数级增长,大数据也开 ...

  10. JVM前奏篇(大局观)

    话不多说直接上干货,先来看oracle官网中是怎么描述JDK的:https://docs.oracle.com/javase/8/docs/index.html 这是官网中JDK.JRE.JVM的一个 ...