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. add jar and proxy repo

    1. 添加代理仓库 2. 添加host 仓库 3. 添加私有jar 4. 添加仓库到public 仓库

  2. 【Linux系列】Centos 7安装 PHP(四)

    目的 为了下面的Laravel部署,本篇开始安装PHP. 设置PHP源 查看Centos源是否有PHP. yum list php* 进一步查看PHP的版本. yum info php.x86_64 ...

  3. mybatis源码学习(一) 原生mybatis源码学习

    最近这一周,主要在学习mybatis相关的源码,所以记录一下吧,算是一点学习心得 个人觉得,mybatis的源码,大致可以分为两部分,一是原生的mybatis,二是和spring整合之后的mybati ...

  4. Python 中国大学排名定向爬虫

    代码来自于中国大学Mooc北京理工大学Pythont教学团队:https://www.icourse163.org/learn/BIT-1001870001#/learn/content?type=d ...

  5. TensorBoard:可视化学习

    数据序列化 TensorBoard 通过读取 TensorFlow 的事件文件来运行.TensorFlow 的事件文件包括了你会在 TensorFlow 运行中涉及到的主要数据.下面是 TensorB ...

  6. 当linux突然修改任何设置都没办法联网时的绝对有效解决办法

    以下操作为重新启动虚拟网卡的相关配置,初始化并重启虚拟网卡,对目前的配置不会有任何影响 打开终端,依次输入以下内容:– sudo service network-manager stop– sudo  ...

  7. SpringSecurity环境下配置CORS跨站资源共享规则

    一.CORS简述 要说明CORS(Cross Origin Resourse-Sharing) 跨站资源共享,就必须先说同源策略.长话短说,同源策略就是向服务端发起请求的时候,以下三项必须与当前浏览器 ...

  8. rsync工具、rsync常用选项、以及rsync通过ssh同步 使用介绍

    第8周5月14日任务 课程内容: 10.28 rsync工具介绍10.29/10.30 rsync常用选项10.31 rsync通过ssh同步 10.28 rsync工具介绍 rsync是一个同步的工 ...

  9. WebGL简易教程(十四):阴影

    目录 1. 概述 2. 示例 2.1. 着色器部分 2.1.1. 帧缓存着色器 2.1.2. 颜色缓存着色器 2.2. 绘制部分 2.2.1. 整体结构 2.2.2. 具体改动 3. 结果 4. 参考 ...

  10. VMware密钥

    UG5J2-0ME12-M89WY-NPWXX-WQH88 GA590-86Y05-4806Y-X4PEE-ZV8E0 YA18K-0WY8P-H85DY-L4NZG-X7RAD UA5DR-2ZD4 ...