深入探究linux

In my last GraphQL post, I talked about the good and bad sides of GraphQL. In this post, we'll take an in-depth look at GraphQL like queries to understand them better and demonstrate how best we can leverage their functionality to build better API's with GraphQL. Without further ado, let's get started!

在上一篇GraphQL帖子中 ,我谈到了GraphQL的优缺点。 在本文中,我们将深入研究GraphQL之类的查询,以更好地理解它们,并展示我们如何最好地利用它们的功能来通过GraphQL构建更好的API。 事不宜迟,让我们开始吧!

查询 ( Queries )

At the bare minimum, GraphQL is just about asking for specific fields on objects. Hence, we can't successfully talk about queries without talking about Fields. Queries are, therefore, the construct used by the client to request specific fields from the server.

至少,GraphQL只是要求在对象上指定特定字段。 因此,如果不谈论字段,就无法成功谈论查询。 因此,查询是客户端用来从服务器请求特定字段的构造。

领域 ( Fields )

Given that GraphQL is structured to optimally expose one endpoint for all requests, queries are structured to request for specific fields and the server equally structured to respond with the exact fields being requested. Consider a situation where a client wants to request for soccer players from an API endpoint, the query will be structured like this:

鉴于GraphQL的结构可以针对所有请求最佳地公开一个端点,因此查询的结构可以请求特定字段,而服务器的结构也同样可以响应所请求的确切字段。 考虑一种情况,当客户希望从API端点请求足球运动员时,查询的结构将如下所示:

{players {name}
}

This is a typical GraphQL query. Taking a closer look, you'll understand that Queries are structurally made up of two distinct parts,

这是一个典型的GraphQL查询。 仔细观察,您将了解查询在结构上由两个不同的部分组成,

  1. The root field (players)  -  which is the object containing the payload and root field (玩家)-是包含有效负载和
  2. The payload itself (name)  -  which is the field(s) requested by the client.payload本身(名称)-客户端请求的字段。

This is an essential part of GraphQL because the server knows exactly what fields the client is asking for and always responds with that exact data. In the case of our query above, we can have this response:

这是GraphQL的重要组成部分,因为服务器确切地知道客户端要查询的字段,并始终以该确切的数据进行响应。 对于上面的查询,我们可以得到以下响应:

{"players": [{"name": "Pogba"},{"name": "Lukaku"},{"name": "Rashford"},{"name": "Marshal"}]
}

The field name returns a String type, in this case, the names of the Manchester United players. However, we are not limited to just Strings, we can have fields of all data types just like the root field players returns an array of items. Feel free to learn more about the GraphQL Type System.

字段name返回String类型,在这种情况下,为曼联球员的名称。 但是,我们不仅限于字符串,我们可以拥有所有数据类型的字段,就像根字段players返回项数组一样。 随时了解有关GraphQL类型系统的更多信息。

In production, we would want to do more than just returning names, the nest could go deeper than that. For instance, in our last query above, we can redefine the query to select an individual player from the list and query for more data on that player. To be able to do such, we'll need a way to identify that player so we can get his details. In GraphQL, we can achieve this with Arguments. We can't talk about queries and not mention arguments so we might as well get to it now. Yeah, let's kill two birds with one stone here.

在生产中,我们不仅要返回名称,还需要做更多的工作,嵌套可能会更深入。 例如,在上面的最后一个查询中,我们可以重新定义查询以从列表中选择一个球员,并查询有关该球员的更多数据。 为了做到这一点,我们需要一种识别该球员的方法,以便我们获取他的详细信息。 在GraphQL中,我们可以使用Arguments.实现此目的Arguments. 我们不能谈论查询,也不能提及参数,所以我们不妨现在就开始讨论。 是的,我们在这里用一块石头杀死两只鸟。

争论 ( Arguments )

GraphQL queries allow us to pass in arguments into query fields and nested query objects. Moreso, you can pass arguments to every field and every nested object in your query to further deepen your request and make multiple fetches. Arguments serve the same purpose as your traditional query parameters or URL segments in REST. We can simply pass them into our query fields to further specify how the server should respond to our request.

GraphQL查询使我们可以将参数传递到查询字段和嵌套查询对象中。 此外,您可以将参数传递给查询中的每个字段和每个嵌套对象,以进一步加深您的请求并进行多次提取。 参数的用途与REST中的传统query parametersURL segments相同。 我们可以简单地将它们传递到查询字段中,以进一步指定服务器应如何响应我们的请求。

Back to our earlier situation of fetching a specific player's kit details like shirt size or shoe size, first, we'll have to specify that player by passing in an argument id to identify the player from the list of players and then we'll define the fields we want in the query payload:

回到我们之前获取特定球员装备详细信息(例如shirt sizeshoe size,首先,我们必须通过传递参数id来指定该球员,以从球员列表中识别球员,然后定义我们在查询有效负载中需要的字段:

@media (max-width: 1280px) { .go-go-gadget-react img:first-child { display: none; } }@media (max-width: 780px) {.go-go-gadget-react { flex-direction: column; }.go-go-gadget-react img { margin-left: 0 !important; margin-bottom: 12px !important; }.header-thingy { margin-top: 20px; }.button-thingy { margin-left: 0 !important; margin-top: 12px !important; }} @media (max-width: 1280px) { .go-go-gadget-react img:first-child { display: none; } }@media (max-width: 780px) {.go-go-gadget-react { flex-direction: column; }.go-go-gadget-react img { margin-left: 0 !important; margin-bottom: 12px !important; }.header-thingy { margin-top: 20px; }.button-thingy { margin-left: 0 !important; margin-top: 12px !important; }}

{player(id : "Pogba") {name,kit {shirtSize,bootSize}}
}

Here, we are requesting the desired fields on the player Pogba because of the id argument we passed into the query. Just like fields, there are no type restrictions, arguments can be of different types too. The result of the query above with the id argument will look like so:

在这里,由于传递给查询的id参数,我们需要在播放器Pogba上请求所需的字段。 就像字段一样,没有类型限制,参数也可以是不同的类型。 上面带有id参数的查询结果如下所示:

{"player": {"name": "Pogba","kit": [{"shirtSize": "large","shoeSize": "medium"             }]}
}

One thing we can perceive as a pitfall here is that GraphQL queries look almost the same for both single items and or lists of items. Sometimes it can get a little confusing which one to expect but luckily, we always know what to expect based on what is defined in the schema. One more thing is, GraphQL queries are interactive, you can add more fields to the root field object at will. That way, you, as the client, have the flexibility to avoid round trips and request for as much data as you want in a single request.

我们可以理解为这里的陷阱之一是,对于单个项目和/或项目列表,GraphQL查询看起来几乎相同。 有时可能会使您感到困惑,但是幸运的是,我们总是根据架构中定义的内容知道期望的结果。 另一件事是,GraphQL查询是交互式的,您可以随意向根字段对象添加更多字段。 这样,作为客户端,您可以灵活地避免往返,并在单个请求中请求所需数量的数据。

That alright. Now, what happens if we want to fetch the same fields for two players, not just one? That's where aliases come in.

没关系 现在,如果我们想为两个玩家而不是一个获取相同的字段会发生什么? 这就是别名的来源。

别名 ( Aliases )

If you take a closer look at our last example, you'll notice that the result object fields

如果仔细看一下我们的最后一个示例,您会注意到result对象字段

// result...."player": {"name": "Pogba","kit": [{"shirtSize": "large","shoeSize": "medium"             }]}

match the query fields

匹配查询字段

//query.... has matching fields with the result
player(id : "Pogba") {name,kit {shirtSize,bootSize}}

but without the argument.

但没有争论。

(id : "Pogba")

Because of this, we can't directly query for the same field player with different arguments, i.e we can't do something like this:

因此,我们无法直接查询具有不同参数的同一个田野player ,即我们不能做这样的事情:

{player(id : "Pogba") {name,kit {shirtSize,bootSize}} player(id : "Lukaku") {name,kit {shirtSize,bootSize}}}

We can't do that, what we can do however is use aliases. They let us rename the result of a field to anything we want. For our example, to query for two players kit details, we'll simply define our query like so:

我们不能这样做,但是我们可以做的就是使用别名。 他们让我们将字段的结果重命名为我们想要的任何内容。 对于我们的示例,要查询两个玩家工具包的详细信息,我们将像这样简单地定义查询:

{player1: player(id: "Pogba") {name,kit {shirtSize,shoeSize}}player2: player(id: "Lukaku") {name,kit {shirtSize,shoeSize}}
}

Here, the two player fields would have conflicted, but since we can alias them to different names player1 and player2, we can get both results in one request like so:

在这里,两个player字段将发生冲突,但是由于我们可以将它们别名为不同的名称player1player2 ,因此我们可以在一个请求中获得两个结果,如下所示:

{"data": {"player1": {"name": "Luke Skywalker","kit": [{"shirtSize": "large","shoeSize": "medium" }]},"player2": {"name": "Lukaku","kit": [{"shirtSize": "extralarge","shoeSize": "large" } ]}}
}

Now using Aliases, we have successfully queried the same field with different Arguments and gotten the expected response.

现在使用别名,我们已经成功地查询了具有不同参数的相同字段,并获得了预期的响应。

操作语法 ( Operation syntax )

Until now, we have been using the shorthand operation syntax where we are not explicitly required to define either the operation name or type. In production, the reverse is the case, though not compulsory, it is advised to use operation names and types to help make your codebase less ambiguous. It also helps with debugging your query in the case of an error.

到现在为止,我们一直在使用速记操作语法,在该语法中,我们没有明确要求定义操作名称或类型。 在生产中,情况相反,尽管不是强制性的,但建议使用操作名称和类型来帮助减少代码库的歧义。 如果出现错误,它也有助于调试查询。

The operation syntax comprises basically of two things:

操作语法基本上包括两件事:

  • The operation type which could be either query, mutation or subscription. It is used to describe the type of operation you intend to carry out.

    operation type可以是查询,变异或订阅。 它用于描述您打算执行的操作类型。

  • The operation name which could be anything that will help you relate with the operation you're trying to perform.

    operation name可以是任何可以帮助您与要执行的操作相关的operation name

Now, we can rewrite our earlier example and add operation type and name like this:

现在,我们可以重写前面的示例,并添加操作类型和名称,如下所示:

query PlayerDetails{player(id : "Pogba") {name,kit {shirtSize,bootSize}}
}

Where: query is the operation type and PlayerDetails is the operation name.

其中: query是操作类型, PlayerDetails是操作名称。

变数 ( Variables )

So far, we have been passing all our arguments directly into the query string. In most cases, the arguments we pass are dynamic. Say for instance, the player the client wants his details comes from a text input form or a dropdown menu. That way, the argument we pass into the query string has to be dynamic and to do that, we need to use variables. What are variables you may ask? variables are basically used to factor out dynamic values from queries and pass them as a separate dictionary.

到目前为止,我们一直在将所有参数直接传递到查询字符串中。 在大多数情况下,我们传递的参数是动态的。 举例来说,客户希望客户提供其详细信息的玩家来自文本输入表单或下拉菜单。 这样,我们传递给查询字符串的参数必须是动态的,为此,我们需要使用变量。 您可能会问什么变量? 变量基本上用于从查询中排除动态值,并将它们作为单独的字典传递。

Considering our last example, if we wanted to make the player dynamic such that the selected player's details are returned, we'll have to store the player's id value in a variable and pass it into the operation name and query argument like so:

考虑我们的最后一个示例,如果我们想使播放器动态化,以便返回所选播放器的详细信息,则必须将播放器的id值存储在变量中,并将其传递给操作名称和查询参数,如下所示:

query PlayerDetails ($id: String){player (id : $id) {name,kit {shirtSize,bootSize}}
}

Here, $title: String is the variable definition and title is the variable name. It is prefixed by $ followed by the type, which in this case is String. This means that we can avoid manually interpolating strings to construct dynamic queries and that is awesome.

在这里, $title: String是变量定义,而title是变量名。 它以$开头,后跟类型,在这种情况下为String。 这意味着我们可以避免手动插入字符串以构造动态查询,这真是太棒了。

###

###

碎片 ( Fragments )

We've come a long way but we are not done yet. Looking at our query, you'll notice that the player field is practically the same for both players:

我们已经走了很长一段路,但我们还没有完成。 查看我们的查询,您会注意到两个球员的player字段几乎相同:

name,kit {shirtSize,bootSize}

To be more efficient with our query, we can extract this piece of shared logic into a reusable fragment on the player field like so:

为了提高查询效率,我们可以将这条共享逻辑提取到player字段上的可重用片段中,如下所示:

{player1: player(id: "Pogba") {     ...playerKit}player2: player(id: "Lukaku") {...playerKit}
}fragment playerKit on player {name,kit {shirtSize,shoeSize}
}

The ability to extract a piece of shared code and reuse across multiple fields is a very crucial concept that helps developers not go DRY - (Don't Repeat Yourself) in development and even in production. If you're working on a deep layered codebase, you'll find it rather useful and timely to reuse code rather than repeat your self across multiply components.

提取一段共享代码并在多个字段之间重用的能力是一个非常关键的概念,它可以帮助开发人员在开发乃至生产中都DRY - (Don't Repeat Yourself) 。 如果您正在使用一个深层次的代码库,您会发现重用代码而不是在乘法组件之间重复自我非常有用且及时。

指令 ( Directives )

GraphQL Directives provides us a way to tell the server whether to include or skip a particular field in when responding to our query. There are basically two built-in directives in GraphQL that helps us achieve just that:

GraphQL指令为我们提供了一种在响应我们的查询时告诉服务器是在其中include还是skip特定字段的方法。 GraphQL中基本上有两个内置指令可以帮助我们实现这一目标:

  1. @skip for skipping a particular field when the value passed into it is true and@skip用于在传递给它的值为true时跳过特定字段,并且
  2. @include to include a particular field when the value passed into it is true 当包含的值为true时, @include include包含特定字段

Let's add a Boolean directive and skip it on the server with the @skip directive:

让我们添加一个Boolean指令,并使用@skip指令在服务器上跳过它

query PlayerDetails ($playerShirtDirective: Boolean!){player(id: "Pogba") {name,kit {shirtSize @skip(if: $playerShirtDirective)bootSize}}
}

The next thing we'll do is to create the playerShirtDirective directive in our query variables and set it to true:

我们要做的下一步是在查询变量中创建playerShirtDirective指令并将其设置为true:

// Query Variables{"itemIdDirective": true
}

This will now return the payload without the shirtSize :

现在,这将返回不包含shirtSize的有效负载:

"player": {"name": "Pogba","kit": [{"shoeSize": "medium"             }]}

We can reverse this situation using the *@include directive. *It works as the opposite of the @skip directive. Needless to show, you can use it to reverse this skip action on the server simply by replacing @skip directive with @include in the query.

我们可以使用* @include指令来扭转这种情况 *与@skip指令相反。 无需显示,只需在查询中用@include替换@skip指令,就可以使用它来逆转服务器上的跳过动作。

结论 ( Conclusion )

In this article, we have gone over the not so popular bits of GraphQL Queries in the simplest way possible. This is in response to the many requests i got to cover Queries after my last GraphQL post. Subsequently, we'll take an in-depth look at other GraphQL features like Mutations and Subscriptions to uncover their unpopular but useful concepts. Until then, Happy New Year.

在本文中,我们以最简单的方式介绍了GraphQL查询中不太流行的部分。 这是对上一篇GraphQL帖子发表后我对查询所涉及的许多请求的回应。 随后,我们将深入研究GraphQL的其他功能,例如Mutations和Subscriptions,以发现它们不受欢迎但有用的概念。 在那之前,新年快乐。

翻译自: https://scotch.io/tutorials/deep-dive-into-graphql-queries

深入探究linux

深入探究linux_深入探究GraphQL查询相关推荐

  1. GraphQL入门之GraphQL查询的规范

    GraphQL查询的规范 GraphQL定义了一套规范,用来描述语法定义,具体参考:http://graphql.cn/learn/queries/ 说明:仅仅是规范,并不是具体实现,需要各种语言进行 ...

  2. GraphQL查询规范

    什么是GraphQL GraphQL是Facebook开发的一套查询语言,和Restful查询规范一样,都是一种对前后端数据交互的一种规范,并不是SQL这种的查询语言. GraphQL和Restful ...

  3. pygame精灵组有哪些方法_小精灵科学室-如何在活动中提高幼儿的探究能力和科学探究活动?...

    小精灵幼儿科学发现室 幼儿科学教育的宗旨,幼儿科学活动的内容. 幼儿为什么要进行科学活动?科学活动的内容都有哪些?科学活动的理念是什么?如何开展科学活动的实施? 幼儿科学教育的宗旨:幼儿科学教育是指幼 ...

  4. 实现根据id查询房源数据的GraphQL服务

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  5. 【Java】探究Java实现多接口时同名方法冲突问题

    问题由来 今天与朋友们聊天谈到C++的多继承问题,朋友觉得非常麻烦,特别是遇到方法重复的时候. 这时,我突然想到既然Java通过多接口的implement代替了复杂的多继承,那如果两个甚至多个接口存在 ...

  6. Skywalking-10:Skywalking查询协议——GraphQL

    GraphQL GraphQL 基础 参照Getting started with GraphQL Java and Spring Boot这篇文章学习即可 PS:可以使用 brew install ...

  7. graphql 嵌套查询_了解GraphQL中的查询

    graphql 嵌套查询 介绍 (Introduction) In this tutorial, we'll take an in-depth look at queries in GraphQL s ...

  8. 几何画板探究圆周角与圆心角关系

    利用几何画板辅助教学可以制作出几乎所有想制作的动画,所制作出的点.线.面.体都可以在各自的路径上以不同的速率和方向进行动画或移动,可以产生良好.强大的动态效果.本教程将介绍如何利用几何画板探究圆周角. ...

  9. 陪孩子一起学python第二季第2集_跟我一起学python | 探究02

    昨天写了"跟我一起学python | 探究01",转发了朋友圈.其实文章序列标题应该写成"跟地理老师一起学Python".我是真正意义上在自学Python.学和 ...

最新文章

  1. 线性表(二)——链表
  2. SAP Analytics Cloud里的Smart Predict
  3. 12 种主流编程语言输出“ Hello World ”,把我给难住了!
  4. 如何让我们的VMware虚拟机上网——转载
  5. BAT中删除整个目录的办法
  6. 快速计算代码行小工具
  7. 《自然语言处理实战入门》 第一章: 自然语言处理(NLP)技术简介
  8. DELL 1420 笔记本 BIOS设置
  9. 初识Python自动化运维(一)
  10. POJ 1625 Censored! (AC自己主动机 + 高精度 + DP)
  11. 人生的差别在于业余时间的利用
  12. 麒麟系统云打印安装指导
  13. mysql pdf微盘下载失败怎么办_mysql线上常见故障剖析.pdf
  14. Framer:开源原型设计工具,巨头们的心头好
  15. my read_exchange rate
  16. 英语语法总结--句子的种类
  17. 什么是“黑天鹅现象”?
  18. 47个经典java程序编程题
  19. iMeta|中科院地球环境研究所王云强组解析了草地土壤微生物生活史策略
  20. 中电金信冰雪运动「数字化转型」赛场,来了一队选手

热门文章

  1. 那些年看过的电影之《绿皮书》
  2. jmeter获取token并请求失败Internal authentication failed 400
  3. cocos creator: 实现伪微信排名
  4. 请使用netty框架实现高效稳定的websocket通信
  5. Logistic Regression 逻辑斯蒂回归
  6. Echarts 图表不能渲染问题整理
  7. 33个机器学习常用数据集
  8. GTP(GPRS Tunnelling Protocol)协议http://blog.csdn.net/stephen_yin/article/details/6951237
  9. Unity (游戏引擎)
  10. FTP修改默认端口后,注意事项