热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:《GraphQL名词101:解析GraphQL的查询语法》译

篇首语:本文由编程笔记#小编为大家整理,主要介绍了《GraphQL名词101:解析GraphQL的查询语法》译相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了《GraphQL 名词 101:解析 GraphQL 的查询语法》译相关的知识,希望对你有一定的参考价值。



The Anatomy of a GraphQL Query

GraphQL 日渐成为数据查询的主流标准之一,整个生态圈也蓬勃发展。本文则由浅入深地详细介绍基础的 GraphQL 格式与关键字,有助于初学者对于 GraphQL 的使用形成体系认知。


GraphQL 日渐成为数据查询的主流标准之一。每天都会产生许多围绕这项技术发展的精彩讨论和新工具。GraphQL最棒的特性就是提供了一个丰富语言集来描述获取数据的API。但是用户该如何描述这种查询语言,以及GraphQL这项核心技术本身呢?let's talk!

GraphQL specification解释了几乎所有出现在GraphQL查询语言中的概念,但是这篇文档实在是太长了,所以我准备在这篇博客中,借助一些具体的栗子来阐述其中一些最重要的概念,来帮助你成为GraphQL专家!至少在纸上谈兵方面 : )



注! 这篇文章可不是GraphQL的入门读物。首先,你应该通读concepts on the graphql.org docs,然后通过Learn Apollo tutorial来学习使用GraphQL,最后当你想继续深入了解这项技术时,再回到这里来吧!



最基本的GraphQL查询

大家通常会使用“查询”来称呼 GraphQL API 服务的一切。但是这样称呼会有太多东西混杂在一起了。我们可能会把我们跪求服务端的一系列行为称为一次查询、一次修改或者一次订阅,但我想“请求(request)”这个词可能更加复合HTTP通信的概念,下面我们先来定义一些最基础的概念:



  • GraphQL 请求体: 使用GraphQL语言定义的一个或多个操作或者数据片段,类型是字符串。


  • 操作: 可以被GraphQL执行引擎理解的一次查询、修改或订阅。


为了搞清楚GraphQL各种基本操作之间的区别,让我们先来看一个简单的GraphQL请求体:





A simple query and its parts.


这个请求体显示了GraphQL的主要构建块,它指定了你尝试获取的数据。



  • 字段(Fields):客户端请求的数据单元,最后作为JSON响应数据中的一个字段。请注意,它们始终称为“字段”,无论它们所在的层次有多深。在你的查询中,对根节点字段的处理和最底层字段应该是一样的。


  • 参数(Arguments):一组与特定字段关联的键值对。这些参数会跟它们相关的字段一起被传递到服务器端执行,并影响服务器对字段的处理方式。如上面的示例,参数可以是字面量,接下来还有参数作为变量形式的栗子。请注意,参数可以显示在任何字段中,即使是嵌套层次很深的字段。


为了让你以非常简洁的形式定义一个GraphQL查询,上面的栗子是GraphQL的一种非常简单的形式。但是在GraphQL操作中三种可选的部分都没有在上述栗子中使用。如果你不仅仅是用GraphQL执行查询操作,或是希望传递动态变量到GraphQL查询中,你就需要利用到这些新的GraphQL特性。

这里恰好有一个包含了所有可选部分的栗子:

《GraphQL 名词 101:解析 GraphQL 的查询语法》【译】



A more detailed query and its parts.




  • 操作类型(Operation type):共三种类型:查询(query)、更新(mutation)、订阅(subscription)。它描述了你试图进行何种操作。然而这些看起来意思很接近的操作,GraphQL服务器处理它们时还是会有一些不同。


  • 操作名称(Operation name):为了方便调试和服务端打日志,最好给你的查询赋予语义化的命名。这样,无论你是在网络日志中或者GraphQL服务器上发现错误,你都可以通过名字很轻松的在代码库中定位问题,而不是靠猜测(类似的工具有 Apollo Optics)。可以把操作名称想象成你最喜欢的编程语言中,一个语义化的函数名。


  • 变量定义(Variable definitions):当客户端向GraphQL服务器发送查询时,会存在查询文档不变,当某些字段会动态变化的情况。这些就是查询中的变量。因为GraphQL是静态类型的,它可以实时验证你是否传递了正确的变量。这正是你声明变量类型时所计划提供的能力。


变量使用特定的序列化协议(在目前的 GraphQL 服务实现中,通常是使用JSON )通过查询文档独立传输。下面是一个变量对象在查询文档中的示例: 

《GraphQL 名词 101:解析 GraphQL 的查询语法》【译】



An example variables object.

可以看到,这里的关键是变量名称需要与变量定义所匹配,其名称是 Episode枚举中的一个成员。




  • 变量(Variables): 它是传递给GraphQL operation的值的字典,提供了operation的动态入参。


这里有一个在谈及Graph的技术意义时很重要,却不常被提及的核心概念——花括号之间的所有东西叫什么? 

《GraphQL 名词 101:解析 GraphQL 的查询语法》【译】

选择集(selection set)是一个会在GraphQL 文档中经常出现的概念,它赋予了GraphQL递归的特性,允许你获取嵌套形式的数据。



  • 选择集(selection set):它是一次operation中需要的一组字段,或者被嵌套在其他的字段中。GraphQL查询必须包含一个标识选择集的字段,且该字段返回的是对象类型,选择集不能设置在返回值是标量类型(Scalar Types)的字段上,例如 Int或者 String



片段(Fragments)

当开始介绍片段(fragments)之后,GraphQL 将变得更加强大。它带来了一系列新的概念。



  • 片段定义(Fragment definition):定义一个片段是GraphQL文档的一部分。为了区别于我们下面会介绍的内联片段,它有时候也被称为片段命名


《GraphQL 名词 101:解析 GraphQL 的查询语法》【译】



A fragment definition and its parts.




  • *片段名称(Fragment name): *片段(fragments )名在GraphQL文档中必须是唯一的。这个名称用于在操作(operations)或者其他片段(fragments )引用片段(fragments )。就像操作(operations)名称一样,片段名也能用于服务端日志调试,所以我们推荐使用明确且有意义的片段(fragments )名。如果你使用了正确的片段(fragments )名,在优化数据获取时,你能够很好的追踪你的代码。


  • 类型条件(Type condition): GraphQL操作总是开始于查询、修改或者订阅schema中的类型,但是片段(fragments )能够用于任一选择,所以为了将校验片段(fragments )与校验schema独立开,你需要指定片段(fragments )能够使用的类型,而这就是类型条件(Type condition)的作用。


就像操作(operations)一样,片段也选择集,使用起来也跟在操作(operations)中使用选择集一样。


在你的操作(operations)中使用片段(fragments )

片段(fragments )只有在操作(operations)中使用才能发挥出作用。片段是 GraphQL 的主要组合数据结构,通过片段可以重用重复的字段选择,减少 query 中的重复内容。接下来我们将介绍使用片段(fragments )的两种方式: 

《GraphQL 名词 101:解析 GraphQL 的查询语法》【译】



  • *片段扩展运算符(Fragment spread): * 当你在操作或者其他片段中使用片段时,你可以将片段名置于 ...之后来表示片段。例如没有片段时需要这样编写 query:










  1. query noFragments {





  2.  user(id: 4) {





  3.    friends(first: 10) {





  4.      id





  5.      name





  6.      profilePic(size: 50)





  7.    }





  8.    mutualFriends(first: 10) {





  9.      id





  10.      name





  11.      profilePic(size: 50)





  12.    }





  13.  }





  14. }





query 中存在下列重复的选择集合:









  1. {





  2.  id





  3.  name





  4.  profilePic(size: 50)





  5. }





可以用片段简化为:









  1. query withFragments {





  2.  user(id: 4) {





  3.    friends(first: 10) {





  4.      ...friendFields





  5.    }





  6.    mutualFriends(first: 10) {





  7.      ...friendFields





  8.    }





  9.  }





  10. }









  11. fragment friendFields on User {





  12.  id





  13.  name





  14.  profilePic(size: 50)





  15. }





使用片段时需要加上 ... 操作符表示展开片段内容,这称为片段扩展运算符(fragment spread),它可以用在任何选择集(selection set)中,用以匹配片段的类型条件。



  • 内联片段(Inline fragment): 如果你仅仅是想执行一些依赖结果类型的字段,却不想把它们抽离成独立的定义,你可以使用内联片段( inline fragment)。它使用起来跟独立的命名片段一样,但是写在查询的内部。有一点不同的是,对于内联片段来说类型条件(type condition)不是必须的,可以像使用指令一样来使用它,接下来我们会演示指令(directive)的栗子。



指令(Directives)

指令是独立于GraphQL server之外的一个附加功能。指令不会对结果的值产生影响,但是会影响哪些结果会被返回,也许还会影响这些结果是如何被执行的。指令可以出现在查询的任何地方,但在这篇文章中我们只关注当前GrahpQL文档所描述的 skip(忽略)和 include(包括) 两个指令。 




You probably wouldn’t usually put all of these in one query, but it’s the easiest way to demonstrate.

你能在上文厨房水槽的栗子中使用指令 skip 和 include。 include 指令表示只有在 if 参数为 true 时才引入片段表示的字段。 skip 指令表示在 if 参数为 true 时忽略片段中的字段。由于指令的语法相当灵活,我们可以利用它来给GraphQL添加更多的特性,而不是使用语法解析或者引入更复杂的工具的方式。




  • *指令(Directive): * 在字段、片段或者查询中的一个注释, include 指令表示只有在 if 参数为 true 时才引入片段表示的字段。 skip 指令表示在 if 参数为 true 时忽略片段中的字段。


  • 指令参数(Directive arguments): 与字段参数类似,只不过它们是被执行引擎处理,而不是传递给字段解析器(field resolver)。



总结

GraphQL 是在应用层对业务数据模型的抽象,是对数据请求定制的 DSQL,它解除了接口和数据之间的绑定,对业务数据结构做了抽象和整理,业务逻辑中的数据依赖于底层数据库结构,并且可以由具体业务场景来定制,不同的业务场景只要基于同样一套基础业务数据模型就可以得到复用,在我看来,这才是 GraphQL 带来的最大改变和收益。 目前GitHub整站API已迁移GraphQL,淘宝也在生成环境有所实践。


参考文档



  • The Anatomy of a GraphQL Query


  • 深入理解 GraphQL




号外号外

IVWEBTLC()5剩1天、仅剩1天、仅剩1天哦!重要的事情说三遍,比手速的时刻到了



推荐阅读
  • 本文详细介绍如何在Spring Boot项目中集成和使用JPA,涵盖JPA的基本概念、Spring Data JPA的功能以及具体的操作步骤,帮助开发者快速掌握这一强大的持久化技术。 ... [详细]
  • 第三周课堂测试1、使用汇编语言编写指令时,用一些简单的容易记忆的符号来代替二进制指令,比机器语言更为方便,属于高级语言。(B ... [详细]
  • 本文详细介绍了MySQL表分区的概念、类型及其在实际应用中的实施方法,特别是针对Zabbix数据库的优化策略。 ... [详细]
  • 本文探讨了Flutter和Angular这两个流行框架的主要区别,包括它们的设计理念、适用场景及技术实现。 ... [详细]
  • 我们正在使用GNU Make来构建我们的系统,在makefile文件的末尾,我们通过一个名为Makedepends的包含来生成一系列的.d文件。然而,当文件被删除或移动时,依赖关系会中断,我们需要寻找一种方法来优雅地处理这种情况。 ... [详细]
  • 设计模式系列-原型模式
    一、上篇回顾上篇创建者模式中,我们主要讲述了创建者的几类实现方案,和创建者模式的应用的场景和特点,创建者模式适合创建复杂的对象,并且这些对象的每个组成部分的详细创建步骤可以是动态的变化的,但 ... [详细]
  • 这个报错出现在userDao里面,sessionfactory没有注入。解决办法:spring整合Hibernate使用test测试时要把spring.xml和spring-hib ... [详细]
  • 探讨如何在C++中,当子类实例存储在父类类型的向量中时,正确访问子类特有的成员变量或方法。 ... [详细]
  • MySQL磁盘空间满的解决方案及预防措施
    本文介绍了一个案例,其中MySQL服务器的磁盘使用率达到100%,仅剩余几十兆空间。通过一系列操作,包括备份数据库、删除实例、删除数据库表以及重启MySQL服务,但未能有效释放磁盘空间。文章进一步探讨了可能的原因和最终解决问题的方法。 ... [详细]
  • 深入理解Java类加载机制及安全防护
    本文探讨了Java类加载的过程,包括加载、验证、准备、解析和初始化五个阶段,并详细解释了每个阶段的具体操作和意义。此外,文章还讨论了Java如何通过双亲委派模型来保障核心API的安全性,以及在特定情况下如何打破这一机制。 ... [详细]
  • PHP网站部署指南:从零开始搭建PHP网站
    本文提供了详细的步骤指导,帮助开发者在不同环境下成功部署PHP网站,包括在IIS和Apache服务器上的具体操作。 ... [详细]
  • 使用EF Core在.Net Core控制台应用中操作SQLite数据库
    本文介绍如何利用Visual Studio 2019和Windows 10环境,通过Entity Framework Core(EF Core)实现对SQLite数据库的读写操作。项目源代码可从百度网盘下载。 ... [详细]
  • 移动端浏览器为了识别用户的双击放大操作,通常会在点击后引入300毫秒的延迟。虽然这种延迟在日常使用中可能不易察觉,但对于需要即时响应的应用(如网页游戏)来说,消除这一延迟至关重要。 ... [详细]
  • 本文详细介绍了Python中的流程控制与条件判断技术,包括数据导入、数据变换、统计描述、假设检验、可视化以及自定义函数的创建等方面的内容。 ... [详细]
  • J2EE平台集成了多种服务、API和协议,旨在支持基于Web的多层应用开发。本文将详细介绍J2EE平台中的13项关键技术规范,涵盖从数据库连接到事务处理等多个方面。 ... [详细]
author-avatar
全拼wangziyiva_632
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有