面向对象的前端开发_面向前端开发人员的GraphQL指南

面向对象的前端开发

by Schalk Venter

由沙克·文特(Schalk Venter)

面向前端开发人员的GraphQL指南 (A guide to GraphQL for front-end developers)

10 months ago, Artsy Engineering Lead, Alan Johnson proclaimed that ‘I have seen the future, and it looks a lot like GraphQL’.

10个月前, Artsy工程负责人Alan Johnson宣称“我已经看到了未来,并且看起来很像GraphQL ”。

Fast-forward to exactly 13 days before I started this article, and Wired Magazine publishes a story title How Facebook has changed computing, highlighting GraphQL as one of the technologies that ‘played a tremendous role in shifting not only in the way we build our servers but also how we write code’.

快到我开始这篇文章之前的13天,《 连线杂志 》( Wired Magazine)发表了一个故事标题, Facebook如何改变了计算 ,着重强调了GraphQL作为一种技术,它不仅在构建服务器的方式上发挥了巨大作用还有我们如何编写代码 '。

These are bold claims! I am by no means qualified to counter nor concur them. However, for me, the above is indicative of how astronomically fast the GraphQL eco-system has grown over the past two years - regardless of whether we think this is for better or for worse.

这些都是大胆的主张! 我绝对没有资格反抗或同意他们。 但是,对我而言,以上说明了GraphQL生态系统在过去两年中的发展速度有多么快-无论我们认为这是好是坏

This growth is also reflected in my day-to-day experience as a developer. Internally at OpenUp, our team has been steadily adopting GraphQL in more and more of our products, due to it solving a lot of pain-points usually associated with the REST API endpoints. Furthermore, we are not alone. GraphQL is widely used by a range of international tech teams from Pinterest, Twitter, Yelp, New York Times, Paypal, Atlassian, Facebook, Github (amongst others); and fellow South African startups like GetTruck, Bettr and Dine4Six.

这种成长也反映在我作为开发人员的日常经验中。 在OpenUp内部,我们的团队已在越来越多的产品中稳定采用GraphQL,因为它解决了通常与REST API端点相关的许多难题。 此外,我们并不孤单。 GraphQL已被PinterestTwitterYelp纽约时报PaypalAtlassianFacebookGithub 众多国际技术团队广泛使用; 以及南非的创业公司如GetTruckBettrDine4Six

After reading the above Wired article I reflected on my own (sometimes turbulent) journey through GraphQL, and I thought that it might be of value to compile a (hopefully!) easy guide for other front-end developers interested in getting started (and avoiding common pitfalls) learning GraphQL.

阅读以上《连线》文章后,我回顾了自己在GraphQL上的经历(有时很动荡),我认为为希望对入门和避免使用感兴趣的其他前端开发人员编写(希望如此)简单指南可能是有价值的常见的陷阱)学习GraphQL。

I’ve broken the below into the following broad topics, so feel free to skip ahead if you are only interested in a specific aspect of GraphQL:

我将以下内容分为以下几个主要主题,如果您只对GraphQL的特定方面感兴趣,请随时跳过:

我自己学习GraphQL的旅程 (My own journey learning GraphQL)

When I first heard about GraphQL I’ve been playing around with this thing called React for a while. I’ve used a bit of Backbone and AngularJS before, but neither really stuck with me.

当我第一次听说GraphQL时,我已经玩了一段时间叫做React的东西了。 之前我曾经使用过BackboneAngularJS ,但两者都没有真正困扰我。

However, I was extremely excited by React’s functional approach to state management and the usage of a Virtual DOM to reduce the performance footprint of intensive DOM manipulations. By this time I’ve essential hand-rolled my own HyperScript-esque helper function to do the above and was looking forward to getting rid of the latter abomination in favour of React.createClass() and React.createElement() .

但是,我对React的状态管理功能方法以及使用虚拟DOM减少密集型DOM操作的性能足迹感到非常兴奋。 到这个时候,我已经基本手动滚动了我自己的HyperScript风格的辅助函数来完成上述任务,并希望摆脱后一种可憎性,而使用React.createClass()React.createElement()

Before giving the above a spin in a production environment I thought it wise to ask a senior team member what he thinks of this React thing. Yet, no good (or perhaps prudent) deed goes unpunished: I was berated with the usual disdain held by a lot of back-end developers at that point (and for some even still today) towards JavaScript frameworks. However (and perhaps as a gesture of goodwill), he did mention that this GraphQL thing (that the team behind React is working on) looks really promising.

在生产环境中进行上述尝试之前,我认为最好问一个高级团队成员对React这个事情的看法。 但是,并没有妥协(也许是审慎的)行为:那时,很多后端开发人员对JavaScript框架持反对态度,这令我感到沮丧。 但是(确实是一种善意的表示),他的确提到了GraphQL的事情(React背后的团队正在努力)看起来确实很有希望。

Which lead me to the following:

这导致我以下几点:

  • Googling GraphQL.

    搜寻GraphQL。

  • Reading a couple of overviews.

    阅读一些概述。

  • Still having no idea what GraphQL is.

    仍然不知道什么是GraphQL。

  • Assuming that it’s probably aimed at web developers with at least one (or multiple) computer science degrees (I guess the way I still feel about Web Assembly and Houdini)

    假设它可能针对具有至少一个(或多个)计算机科学学位的Web开发人员(我想我仍然对Web AssemblyHoudini的看法 )

  • Going on with my life.

    继续我的生活。

A couple of years later, after being sucked in by the gravitational pull of the front-end supernova that has become the React ecosystem, I started playing around with another tool called Gatsby. I’ve been struggling to get React Helmet to play nice with my own Frankenstein React static site generator built on top of static-site-generator-webpack-plugin.

几年后,在前端超新星的引力吸引下,React生态系统吸引了我,之后,我开始研究另一个名为Gatsby的工具。 我一直在努力让React Helmet与我自己的建立在static-site-generator-webpack-plugin之上的Frankenstein React静态站点生成器配合使用

I actually found a message in the #react Slack channel on ZA Tech that nicely encapsulates the frustration I felt at that time:

我实际上在ZA Tech#react Slack频道中找到一条消息,很好地概括了我当时的沮丧#react

September 14th, 2017

2017年9月14日

Schalk Venter 4:02 PM

Schalk Venter下午4:02

I might be missing something obvious here ?

我可能在这里缺少明显的东西

Schalk Venter 4:38 PM

Schalk Venter下午4:38

However, either I’m misunderstanding the documentation or server-side rendering is not as easy as they make it out in the docs. ?

但是,我误解了文档,或者服务器端渲染并不像他们在文档中说明的那样容易。

So this Gatsby-thing seemed to give me what I was trying to hack together by other means. However, I was met with further frustration as I came to realise that Gatsby is in cahoots with my previous nemesis, GraphQL (as a means to query front-matter and textual content from Markdown files). However, going back to my Frankenstein-mess really didn’t seem to be compelling either.

因此,这种盖茨比的东西似乎给了我我试图通过其他方式一起入侵的东西。 但是,当我意识到盖茨比与我以前的克星GraphQL(作为从Markdown文件中查询重要内容和文本内容的手段)陷入困境时,我感到更加沮丧。 但是,回到我的科学怪人看来也不是很吸引人。

Turns out I really didn’t have a choice but to learn GraphQL at this point.

事实证明,我现在别无选择,只能学习GraphQL。

This meant that I needed to find answers to the following:

这意味着我需要找到以下答案:

那么GraphQL到底是什么? (So what exactly is GraphQL?)

“I have seen the future, and it looks a lot like GraphQL. Mark my words: in 5 years, newly minted full-stack app developers won’t be debating RESTfulness anymore, because REST API design will be obsolete. […] It lets you model the resources and processes provided by a server as a domain-specific language (DSL). Clients can use it to send scripts written in your DSL to the server to process and respond to as a batch.”

“我已经看到了未来,它看起来很像GraphQL。 谨记我的话:在5年内,新成立的全栈应用程序开发人员将不再辩论RESTfulness ,因为REST API设计将过时。 […]它使您可以将服务器提供的资源和过程建模为特定领域语言(DSL)。 客户可以使用它来将用DSL编写的脚本发送到服务器,以进行批处理和响应。”

Alan Johnson (Is GraphQL The Future?)

艾伦·约翰逊 ( GraphQL是未来吗? )

Yikes, that probably wasn’t the answer that I (nor you, dear reader) were looking for!

Yikes,这可能不是我(亲爱的读者,您也不想要)寻找的答案!

域是什么? (Domain-what-a-thing?)

However, as scary as the above definition seems, it is important to unpack it a bit if we want to get to the root of what exactly GraphQL is.

但是,如上面的定义所显示的那样令人恐惧,要想了解GraphQL的确切含义,一定要对其进行一些打包。

Let’s start with the term ‘domain-specific language’:

让我们从术语“特定领域的语言”开始

  1. First and foremost, a domain-specific language (also called a mini-language) is a programming language created to express a very specific and predefined type of digital information (a domain). Whereas a general purpose language like JavaScript can (similar to a Swiss army knife) be used to express a range of digital information (and in some cases, even information that its creators didn’t anticipate at inception). This includes everything from low-level primitives like objects, functions, strings, symbols to general programming patterns like HTTP requests, DOM manipulations and/or online data storage). Domain-specific languages tend to be more limited (and intentionally so) in what they are able to express when compared to general-purpose programming languages.

    首先,领域特定的语言(也称为迷你语言 )是一种编程语言,旨在表达非常特定和预定义的数字信息类型(领域)。 可以使用JavaScript这样的通用语言 (类似于瑞士军刀)来表达一系列数字信息( 在某些情况下,甚至包括其创建者一开始就没想到的信息 )。 这包括从对象函数字符串符号等低级原语到HTTP请求DOM操作和/或在线数据存储之类的通用编程模式的所有内容。 与通用编程语言相比,领域特定语言在表达能力上往往受到更多限制(有意地如此)。

  2. Secondly, DSL’s are often plugged into other DSL’s or general purpose languages to piggyback on existing functionality (due to their limited scope). However, this does not mean that DSL’s are tied to specific languages (GraphQL being an example of this). For example, the (more or less defunct now) XForms DSL can be used inside HTML (which itself is a DSL on top of another DSL called SGML), while at the same time it can also be used in a general purpose language like Java.

    其次, DSL通常被插入其他DSL或通用语言中,以piggy带现有功能(由于其范围有限)。 但是,这并不意味着DSL绑定到特定的语言(GraphQL就是这种示例)。 例如,(现在或多或少已经不存在的) XForms DSL可以在HTML内使用(它本身是在另一个称为SGML的DSL之上的DSL),与此同时,它也可以在通用语言(如Java)中使用

Is this getting a bit too nerdy?

这有点书呆子吗?

Right, let’s bring it back! You probably have more experience with DSL’s than you realise (and not only through HTML!), but one or more of the following:

对,让我们把它带回来! 您可能比DSL拥有更多的经验(不仅通过HTML!),而且还具有以下一种或多种:

Furthermore, you probably already have first-hand experience of their narrow scope. Most people will roll their eyes if I attempt to manage a database by means of HTML or control a spacesuit via CSS.

此外,您可能已经具有范围狭窄的第一手经验。 如果我尝试通过HTML来管理数据库或通过CSS来控制太空服 ,那么大多数人都会睁大眼睛。

DSL的真正价值 (The real value of DSL’s)

However, because of their very narrow scope, DSL’s tend to be extremely expressive (in other words, easy to read and write) compared to general purpose languages.

但是,由于它们的范围非常狭窄,所以与通用语言相比,DSL倾向于表现力极强(换句话说,易于读写)。

As an example:

为例 E:

A friend (and ex-colleague) of mine, Greg Kempe uses a DSL called Akoma Ntoso (built on XML) in his non-profit project called Open By-laws. Akoma Ntoso (meaning ‘linked hearts’ in Akan) is a DSL built exclusively to express parliamentary, legislative and judiciary documents in a digital manner.

Greg Kempe是我的朋友(和前同事),在他的非盈利项目Open By-laws中使用了称为Akoma Ntoso (基于XML )的DSL。 Akoma Ntoso(在阿寒语中意为“ 链接的心 ”)是一种专用于以数字方式表达议会,立法和司法文件的DSL。

For example, see below a section of the city of Cape Town’s outdoor signage by-law (expressed in Akoma Ntoso):

例如,请参阅以下开普敦市户外路标法规的一部分 (以阿科玛·恩托索表示):

将其带回前端开发 (Bringing this back to front-end development)

To illustrate the above in the context of front-end development we can look at a common example where we update our website’s Document Object Model (DOM) via JavaScript (in order to show a specific message when a user is logged in):

为了在前端开发的上下文中说明上述内容,我们可以看一个常见的示例,在该示例中,我们通过JavaScript更新了网站的文档对象模型 (DOM)(以便在用户登录时显示特定消息):

You can see it in action inside the following Codepen example:

您可以在下面的Codepen示例中看到它的运行情况:

As powerful as JavaScript (even with the above ES6 syntax is), it isn’t very expressive when working with the DOM. Fortunately, there is a DSL specifically designed to better express browser DOM nodes. You might know it as HTML (or by the full name: Hypertext Markup Language).

与JavaScript一样强大(即使使用上述ES6语法也是如此),但在处理DOM时,它的表达能力不是很好。 幸运的是,有一种专为更好地表达浏览器DOM节点而设计的DSL。 您可能将其称为HTML(或全名:超文本标记语言)。

This means that we can use the innerHTML property (only added to JavaScript back with Internet Explorer 4) to re-write the above. The innerHTML property accepts a string written in HTML DSL:

这意味着我们可以使用innerHTML属性(仅通过Internet Explorer 4重新添加到JavaScript中)来重写上面的内容。 innerHTML属性接受用HTML DSL编写的字符串:

As you can see we still get the exact same behaviour:

如您所见,我们仍然得到完全相同的行为:

最后一件事 (One last thing)

Lastly, before we get into the GraphQL DSL itself, it might be of value to draw a distinction between DSL’s and superset languages like TypeScript or Sass. While a superset language is meant to extend an existing language’s grammar, a DSL does not need to adhere to any underlying language or environment. For example, JSX (built on top of XML) can be used to either interface directly with the browser DOM or a mobile operating system in the form of a mobile app (by means of React Native).

最后,在进入GraphQL DSL本身之前,区分DSL和超集语言(如TypeScriptSass)可能是有价值的。 虽然超集语言旨在扩展现有语言的语法,但DSL无需遵循任何基础语言或环境。 例如, JSX (基于XML )可以用于直接与浏览器DOM交互,也可以用于以移动应用程序形式(通过React Native )的移动操作系统

Stop before you type that angry reply! I’m aware that the above distinction between DSLs/general purpose languages and DSLs/superset languages is fuzzy in a lot of cases, and (much like the disputed difference between websites and webapps) is subject to the Sorites paradox. However, as is true with all cases of the Sorites paradox, fuzzy distinctions exist (in spite of their lack of scientific rigour) specifically because of the value they provide when explaining the nature of day-to-day experiences. So let’s merely call the above definition this article’s working definition of DSLs.

在键入该愤怒的回复之前先停下来! 我知道DSL /通用语言和DSL /超集语言之间的上述区别在很多情况下是模糊的,并且(很像网站和Web应用程序之间有争议的区别)受Sorites悖论的约束。 但是,正如所有Sorites悖论的情况一样,存在模糊的区别(尽管缺乏科学严谨性),特别是因为它们在解释日常体验的本质时提供了价值。 因此,我们仅将以上定义称为本文对DSL的有效定义

GraphQL试图解决什么问题? (What problem is GraphQL trying to solve?)

Similar to the above, GraphQL was created internally by the tech team behind Facebook in 2012 as a DSL to write more expressive (and powerful) data queries in the Facebook mobile app (to a remote data API).

与上述类似,GraphQL由Facebook背后技术团队在2012年内部创建,它是一种DSL,用于在Facebook移动应用程序中向远程数据API编写更具表现力(且功能强大)的数据查询。

The problem: Common REST (or Representational State Transfer) API approaches mostly rely on fixed data structures. This means that after enough iteration, most REST API’s end up requiring a Lernaean Hydra of queries to get a specific piece of data.

问题:常见的REST(或表示状态传输)API方法主要依赖固定数据结构。 这意味着经过足够的迭代,大多数REST API最终都需要Lernaean Hydra查询才能获取特定的数据。

In short (as noted by Chimezie Enyinnaya, a Nigerian content creator for Pusher — a service that manages remote pub/sub messaging):

简而言之(正如尼日利亚Pusher内容创建者Chimezie Enyinnaya所指出的那样 ,该服务是管理远程发布/ 订阅消息传递的服务):

“With REST, we might have a /authors/:id endpoint to fetch an author, then another /authors/:id/posts endpoint to fetch the post of that particular author. Lastly, we could have a /authors/:id/posts/:id/comments endpoint that fetches the comments on the posts. […] It is easy to fetch more than the data you need with REST, because each endpoint in a REST API has a fixed data structure which it is meant to return whenever it is hit.”

“使用REST,我们可能有一个/authors/:id端点来提取作者,然后有另一个/authors/:id/posts端点来获取该特定作者的帖子。 最后,我们可以有一个/authors/:id/posts/:id/comments端点,该端点可以获取帖子的评论。 […]使用REST可以轻松获取比您需要的数据更多的数据,因为REST API中的每个端点都有一个固定的数据结构,该数据结构可以在命中时返回。

Chimezie Enyinnaya (REST versus GraphQL)

Chimezie Enyinnaya ( REST与GraphQL对比 )

In fact, this is so common that GraphQL is just one of several solutions that were conjured up to solve this problem:

实际上,这是如此普遍,以至于GraphQL只是为解决该问题而想到的几种解决方案之一:

“Interestingly, other companies like Netflix or Coursera were working on comparable ideas to make API interactions more efficient. Coursera envisioned a similar technology to let a client specify its data requirements and Netflix even open-sourced their solution called Falcor.”
“有趣的是,像Netflix或Coursera这样的其他公司正在研究可比的想法,以提高API交互的效率。 Coursera设想了一种类似的技术,可以让客户指定其数据要求,而Netflix甚至开源了其解决方案Falcor。

How to GraphQL (GraphQL fundamentals: Introduction)

如何使用GraphQL ( GraphQL基础知识:简介 )

However, contrary to some of the above, GraphQL was released three years later under the MIT license and today forms the backbone behind open-source services like Apollo (using GraphQL to read and/or change both local and remote app state) or even Gatsby (using GraphQL to query front-matter and textual content from markdown files).

但是,与上述某些情况相反,GraphQL是在MIT许可下三年后发布的 ,如今已成为诸如Apollo (使用GraphQL读取和/或更改本地和远程应用程序状态)甚至Gatsby之类的开源服务的Struts。 (使用GraphQL从markdown文件中查询主题和文本内容)。

So without further ado, let’s get to the meat of this section: A real-world working example that actually illustrates how GraphQL solves the above problem.

因此,不费吹灰之力,让我们开始本节的内容:一个实际的工作示例,实际说明了GraphQL如何解决上述问题。

For argument's sake, let’s say that I want to know the number of users following me on Github. We can easily retrieve the data via the native JavaScript fetch method (from the Github REST API), and then display a list of usernames in the DOM via an unordered list (by means of the innerHTML example illustrated above):

为了论证,假设我想知道在Github上关注我的用户数量 。 我们可以轻松地通过本机JavaScript fetch方法(从Github REST API )检索数据,然后通过无序列表(通过上面显示的innerHTML示例)在DOM中显示用户名列表:

Surprisingly straightforward right?

出人意料的简单吧?

However, getting a list of followers doesn’t really tell us much. We want to get a sense of how prominent these users are on Github (since a follow from Dan Abramov should be weighed differently than a follow from Johnny the team intern). In order to accomplish this, I will be using the extremely unscientific concept, which I henceforth deem Github Equity™ (similar to the search engine concept of Link Equity). Github Equity™ will be calculated by means of the total repositories maintained by a user and their own amount of followers.

但是,获得关注者列表并不能真正告诉我们很多。 我们想了解这些用户在Github上的杰出程度(因为对Dan Abramov的关注与对团队实习生Johnny的关注的权衡应该有所不同)。 为了实现此目的,我将使用极其不科学的概念,此后我将其视为Github Equity ™(类似于Link Equity的搜索引擎概念)。 Github Equity ™将通过用户和他们自己的关注者维护的总存储库来计算。

In short:

简而言之:

Total Repositories * Total Followers

Total Repositories * Total Followers

Pretty easy! However, getting the data required to perform this calculation is a bit trickier since it would require several asynchronous requests REST queries (requiring some orchestration by means of native JavaScript Promises):

挺容易! 但是,获取执行此计算所需的数据有些棘手,因为它将需要多个异步请求REST查询(需要通过本机JavaScript Promises进行一些编排):

As data queries go the above is still well within the bounds of what would be considered reasonable. However, all the required REST API calls (running in parallel!) make the code extremely hard to read and modify. This means that even if we only get the needed information from the first 10 followers, it would amount to a total of 31 REST API calls. Meaning that we quickly run into the default Github API rate limit (a limit on the amount of request the API accepts from a specific IP in the span of an hour)

随着数据查询的进行,上述内容仍在合理范围之内。 但是,所有必需的REST API调用(并行运行!)使代码极难阅读和修改。 这意味着,即使我们仅从前10个关注者那里获得所需的信息,也将总共有31个REST API调用。 这意味着我们很快就遇到了默认的Github API速率限制 (在一个小时的时间内对API从特定IP接受的请求数量的限制)

You can see this happening in the below Codepen, where it should output the following error to the DOM if run a couple of times in a single hour (click the rerun button in the bottom right corner a couple of times) : TypeError: response.map is not a function. In other words, the API did not return the required array (since .map() can only be run on iterables in JavaScript):

您可以在下面的Codepen中看到这种情况,如果在一个小时内rerun几次(应单击右下角的rerun按钮两次) ,它将在DOM中输出以下错误: TypeError: response.map is not a function 。 换句话说,API没有返回所需的数组(因为.map()可在JavaScript中的可迭代对象上运行):

Lucky for us (in addition to the above REST API) Github also exposes a GraphQL endpoint by means of the following: https://api.github/graphql. This means that we can re-write the above as follows in the GraphQL DSL:

对于我们来说很幸运(除上述REST API之外),Github还通过以下方式公开了GraphQL端点https://api.github/graphql 这意味着我们可以在GraphQL DSL中重新编写上面的代码:

If you haven’t encountered GraphQL before the above might look a bit bewildering. However, we’ll unpack the syntax a bit in the upcoming section.

如果您之前没有遇到GraphQL,可能看起来有些困惑。 但是,我们将在接下来的部分中对语法进行一些整理。

As an aside, we are doing a very low-level/hand-rolled implementation of GraphQL for illustrative purposes. When encountering GraphQL in the wild you will most probably encounter it by means of Apollo (developed by the team behind Meteor) or Relay (developed by the team behind Facebook). These libraries are essentially just tooling that makes it easier to work with GraphQL on the client-side.

顺便说一句,出于说明目的,我们正在对GraphQL进行非常底层/手动的实现。 在野外遇到GraphQL时,您很可能会通过Apollo (由Meteor背后的团队开发)或Relay (由Facebook背后的团队开发)来遇到它。 这些库本质上只是工具,可以更轻松地在客户端上使用GraphQL。

GraphQL相当于“ Hello World!” (The GraphQL equivalent of ‘Hello World!’)

Queries and Subscriptions and Mutations, Oh my!

查询,订阅和变异,天哪!

Personally for me, when I’m just starting out with a new programming language (even if it’s a DSL like GraphQL) there is often (what seems like) an impossible amount of information to take in. In order to make this process a bit more manageable, I (without fail) always start with the same question: What is to the ‘Hello World!’ equivalent of this language (often followed by what is the To-do app equivalent of this language).

就我个人而言,当我刚开始使用一种新的编程语言(即使是像GraphQL这样的DSL)时,通常也(似乎)要吸收大量信息。为了更易于管理,我(不会失败)总是从相同的问题开始:“ Hello World! 等价于该语言(通常后面跟等价于该语言的To-do应用程序)。

In short:

简而言之:

A “Hello, World!” program generally is a computer program that outputs or displays the message “Hello, World!”. Because it is very simple in most programming languages, it is often used to illustrate the basic syntax of a programming language and is often the first program that those learning to code write.
“你好,世界!” 程序通常是输出或显示消息“ Hello,World!”的计算机程序。 因为它在大多数编程语言中都非常简单,所以通常用于说明一种编程语言的基本语法,并且通常是那些学习编码的人编写的第一个程序。
A “Hello, World!” program is traditionally used to introduce novice programmers to a programming language.
“你好,世界!” 传统上,该程序用于将新手程序员介绍给编程语言。

Wikipedia ("Hello, World!” program)

维基百科 ( “ Hello,World!”程序 )

So what is the ‘Hello World!’ equivalent in GraphQL?

那么什么是“ Hello World!” 等价于GraphQL?

According to Julian Mayorga in his book, Fullstack GraphQL, ‘In its simplest form, GraphQL is all about asking for specific fields of objects’. Something called client‐specified queries in the original 2015 GraphQL spec:

根据Julian Mayorga在他的书Fullstack GraphQL中所说 ,“ 以最简单的形式,GraphQL就是要求对象特定字段 ”。 原始2015 GraphQL规范中称为客户指定的查询

These queries are specified at field‐level granularity. In the majority of client‐server applications written without GraphQL, the server determines the data returned in its various scripted endpoints. A GraphQL query, on the other hand, returns exactly what a client asks for and no more.
这些查询以字段级别的粒度指定。 在大多数不使用GraphQL编写的客户端服务器应用程序中,服务器确定在其各个脚本化端点中返回的数据。 另一方面,GraphQL查询仅返回客户要求的内容,而不再返回。

GraphQL Working Draft (July 2015)

GraphQL工作草案(2015年7月 )

However, what separates a GraphQL ‘Hello World!’ from (for example) a JavaScript console.log('Hello World!') is that we need to connect our query to something that is queryable.

但是,是什么分开了GraphQL“ Hello World!” 来自(例如)JavaScript console.log('Hello World!')是我们需要将查询连接到可查询的对象。

Luckily there are several public GraphQL endpoints available on the internet. From a Stanford University endpoint that allows one to query HIV drug resistance data to an endpoint that houses a collection of public demographic information arranged by country.

幸运的是,互联网上有几个公共的GraphQL端点 。 从允许询问HIV耐药性数据的斯坦福大学(Stanford University)端点到一个端点(该端点包含一个按国家排列公共人口信息)的端点。

However, let us direct our gaze on the pinnacle of human technological achievement: a Pokéapi that supplies ‘ all the Pokémon data you’ll ever need’.

但是,让我们将目光聚焦在人类技术成就的顶峰上:提供“您需要的所有神奇宝贝数据”的神奇宝贝。

As a warm-up exercise lets create the following query (you can follow along if you want):

作为热身练习,让我们创建以下查询( 如果需要,您可以按照以下说明进行操作):

{  pokemons (first: 20) {    name  }}

Meh! That was quite underwhelming: a list of 20 Pokemon from the Pokedex. However, let’s turn it up a notch and find something more specific (which if you remember correctly is where GraphQL really shines!).

Me! 那是相当给人留下深刻印象:从20口袋妖怪名单图鉴 。 但是,我们将其调高一个档次并找到更具体的内容(如果您没记错的话,这就是GraphQL真正发挥作用的地方!)。

To make it interesting let’s say that we want to determine the average weight of Pikachu’s final evolution (spoiler: it’s Raichu). We can use the following query (link to live example):

为了使它有趣,我们假设要确定皮卡丘最后一次进化的平均重量(破坏者: Raichu )。 我们可以使用以下查询( 链接到实时示例 ):

It is important to note that the above query is essentially shorthand for the following:

重要的是要注意,以上查询实质上是以下各项的简写:

query GetPikachuEvolutionWeight {  pokemon(name: "Pikachu") {    evolutions {      weight {        minimum        maximum      }    }  }}

The fact that GraphQL assumes you will be doing a query even when you don’t specify an action shows how central queries are to GraphQL.

GraphQL假设即使您未指定操作也将执行查询,这一事实说明了对GraphQL进行集中查询的方式。

Regardless, no matter which of the above we use, we will get the following JSON response from the endpoint:

无论使用哪种方法,我们都会从端点获得以下JSON响应:

This means that we can just run our parse() function (from the above example) on this JSON response, and output the result (29.5) to the DOM.

这意味着我们可以仅在此JSON响应上运行parse()函数(来自上述示例),然后将结果(29.5)输出到DOM。

In short, it can be said that queries are little maps in the form of Strings (no, not this kind!) used by GraphQL to navigate a data-structure to find all requested items in a single journey.

简而言之,可以说查询是GraphQL使用的字符串形式的小映射( 不,不是这样 !),用于导航数据结构以在一次旅程中查找所有请求的项目。

This means that we can (for the fun of it) write a similar set of real-world instructions in the GraphQL DSL:

这意味着我们可以(出于乐趣)在GraphQL DSL中编写一组类似的实际指令:

我应该以什么顺序学习GraphQL概念? (In what order should I learn GraphQL concepts?)

Thus far we’ve only touched on queries. However (and perhaps surprisingly), you can get pretty far with GraphQL by just understanding the above. However, there are several additional concepts that you might want to look into if you want to use GraphQL to its full potential:

到目前为止,我们仅涉及查询。 但是,(也许令人惊讶),仅通过了解以上内容,您就可以使用GraphQL取得更远的成就。 但是,如果您想充分利用GraphQL的潜力,可能还需要研究几个其他概念:

Additional tooling/concepts used by GraphQL queries:

GraphQL查询使用的其他工具/概念:

  1. Fields: This is the items in a query that at face-value resemble keys in a JavaScript object. For example paper , post_office and travel in the above example.

    字段 :这是查询中的项目,其表面价值类似于JavaScript对象中的键。 在上面的示例中,例如paperpost_officetravel

  2. Arguments: Optional information we can pass to fields. For example type: drive and amount: 12 in our example above.

    参数 :我们可以传递给字段的可选信息。 例如,在上面的示例中, type: driveamount: 12

  3. Aliases: A custom name that should be used for the JavaScript key to which a field resolves. By default, the object key is the same name as the field. For example in the above post_office will resolve to { post_office: { ... } } . However, we can alias it as follows: postOffice: post_office , which will return { postOffice: { ... } } . Not only is this useful if we want to make the key more semantic or change the casing, but this is also useful when we are using the same field twice (to prevent the default key of the second post_office from overriding the first post_office value.

    别名 :一个自定义名称,该名称应用于字段解析为JavaScript密钥。 默认情况下,对象键与字段名称相同。 例如,在上面的post_office中将解析为{ post_office: { ... } } 。 但是,我们可以使用以下别名: postOffice: post_office ,它将返回{ postOffice: { ... } } 。 这不仅在我们想要使键更具语义或更改大小写时有用,而且在我们两次使用同一字段时也很有用(以防止第二个post_office的默认键覆盖第一个post_office值。

  4. Variables: When I first started using GraphQL, I did what any reasonable developer would do. I just used dynamic interpolation in the query (expressed through a template literal). In other words, I would do the following for our Pokemon example above: pokemon (name: "${dynamicValue)"). Much to the shock of fellow GraphQL developers (since I’m essentially creating side-effects all over the place)! Turns out that GraphQL has built-in functionality to pass external values into a query. By declaring the variable at the query root. For example with query GetPokemonEvolutionWeight($name: string) and pokemon (name: $name) we can simply pass an object of variables to the query when it gets called (i.e. { name: 'Pikachu' } . Note that you need to assign one of the core GraphQL scalar types to a variable (for example we used string above). It is possible to create your own custom types, but this is outside of the scope of this article.

    变量 刚开始使用GraphQL时,我做了任何合理的开发人员都会做的事情。 我只是在查询中使用了动态插值(通过模板文字表示)。 换句话说,我将对上面的Pokemon示例执行以下操作: pokemon (name: "${dynamicValue)") 。 令GraphQL开发人员感到震惊的是(因为我本质上是在各处产生副作用)! 事实证明GraphQL具有内置功能,可以将外部值传递到查询中。 通过在查询根目录中声明变量。 例如,使用query GetPokemonEvolutionWeight($name: string)pokemon (name: $name)我们可以在调用查询时将变量的对象简单地传递给查询(即{ name: 'Pikachu' } 。请注意,您需要分配变量的核心GraphQL标量类型之一 (例如,我们在上面使用string )可以创建自己的自定义类型,但这不在本文讨论范围之内。

Furthermore, you might also be interested in venturing past queries only (covered in this article) into more advanced GraphQL features:

此外,您可能也有兴趣仅将过去的查询(本文中介绍)引入更高级的GraphQL功能:

  • Mutations: Thus far we’ve only been fetching data via GraphQL. However, it is also possible to send data via GraphQL. This is done via Mutations, which are the GraphQL equivalent of POST in traditional REST API endpoints.

    变异 :到目前为止,我们仅通过GraphQL获取数据。 但是,也可以通过GraphQL发送数据。 这是通过Mutations完成的,Mutations在传统的REST API端点中相当于POST的GraphQL。

  • Subscriptions: This is essentially traditional GraphQL queries in reverse. Instead of sending a request to the server to retrieve data we tell the server to let us know when data changes and to send the updated data to us as defined in the subscription.

    订阅 :本质上是反向的传统GraphQL查询。 而不是向服务器发送检索数据的请求,我们告诉服务器让我们知道数据何时发生更改,并按照订阅中的定义将更新的数据发送给我们。

后端呢? (What about the back-end?)

In short, when I initially asked myself this question 3 years ago the answer was a resounding:

简而言之,当我三年前最初问自己这个问题时,答案是轰动一时的:

Don’t even worry about it.

甚至不用担心。

Furthermore, I’m not sure whether my response has changed since. I still have no idea what Gatsby does behind the scenes to convert my markdown (via gatsby-transformer-remark) and JSON (via gatsby-transformer-json) content into a GraphQL endpoint.

此外,我不确定此后的React是否发生变化。 我仍然不知道Gatsby在幕后如何将markdown(通过gatsby-transformer-remark )和JSON(通过gatsby-transformer-json )内容转换为GraphQL端点。

This is not due to apathy, quite the contrary in fact! I’m a big fan of Gatsby and busy working on a pull request to trigger prefetching of pages programmatically. Given how self-documenting GraphQL is, I have yet to have a need to peek under the hood in terms of how Gatsby handles GraphQL — regardless of how complex my query or data gets. Furthermore, there are several other GraphQL services that I use (for example GraphCMS) where I can say the exact same.

这不是由于冷漠,实际上恰恰相反! 我是Gatsby的忠实粉丝,忙于处理请求请求以编程方式触发页面预取 。 鉴于GraphQL的自我记录功能,无论盖茨比如何处理GraphQL,无论我的查询或数据变得多么复杂,我都无需深入了解。 此外,我还可以使用其他几种GraphQL服务(例如GraphCMS ),在这里我可以说完全相同。

Does this mean that there is no value in learning how to configure a GraphQL server?

这是否意味着学习如何配置GraphQL服务器没有任何价值?

Certainly not!

当然不是!

As with anything understanding how something works under the surface (whether it be JavaScript, CSS or even the browser itself) makes it easier to debug things when they do go wrong. However, the fact that I’ve only started digging into the back-end side of GraphQL recently goes to show how far you can get without knowing anything about how the endpoint gets created behind the scenes.

就像对任何事物的理解一样,无论事物是在表面下如何工作(无论是JavaScript,CSS还是浏览器本身),都可以在出错时更容易地对其进行调试。 但是,最近我才刚刚开始研究GraphQL的后端这一事实表明,在不了解有关如何在后台创建端点的任何知识的情况下,您可以得到多大的收益。

However, if you are interested in learning how to set up a custom GraphQL server you can have a look at GraphQL for Back-end Developers by my good friend Shailen Naidoo. He is a phenomenal developer and the reason why I’m even looking at the back-end side of GraphQL in the first place.

但是,如果您有兴趣学习如何设置自定义GraphQL服务器,可以由我的好朋友Shailen Naidoo看一下GraphQL for Back-end Developers 。 他是一位杰出的开发人员,也是我什至首先关注GraphQL后端的原因。

最后的话 (Final Word)

First and foremost, well done if you’ve read this entire wall of text from top to bottom. It’s quite lengthy! I started writing it mostly in response to the lack of front-end specific introductions to GraphQL. This meant that there was quite a bit of ground to cover.

首先,如果您已经从上到下阅读了整整一堵文本墙,那就做得很好。 很长! 我开始编写它主要是因为缺少对GraphQL的前端特定介绍。 这意味着要覆盖很多地方。

Secondly, I am by no means an expert on GraphQL so if there are resources/references that I missed or you feel would help front-end developers get started on GraphQL, then please let me know in the comments. I’m more than happy to add it.

其次,我绝不是GraphQL的专家,因此,如果我错过了一些资源/参考,或者您认为这将有助于前端开发人员开始使用GraphQL,请在评论中告诉我。 我很高兴添加它。

Lastly, if there are any inaccuracies also feel free to call me out in the comments!

最后,如果有任何不准确之处,请随时在评论中打扰我!

If you’re interested in learning more about GraphQL check out the following resources:

如果您有兴趣了解有关GraphQL的更多信息,请查看以下资源:

Lastly, thanks for the feedback and input provided by Shailen Naidoo and Zeeshaan Maudarbocus.

最后,感谢Shailen NaidooZeeshaan Maudarbocus提供的反馈和意见。

Follow me on Github, I’m always curious as to what everyone in the tech field is working on — so I’ll probably follow you back! ?

在Github上关注我 ,我一直对技术领域的每个人都在做什么感到好奇-所以我可能会跟着你回来!

schalkventer - Overview? Front-end Development / ? UI Design / ? Social Good / ❤️ Destigmatising Mental Illness - schalkventergithub.com

schalkventer-概述 前端开发/? UI设计/? 社会公益/❤️污名化心理疾病-schalkventergit hub.com

翻译自: https://www.freecodecamp.org/news/graphql-for-front-end-developers-1f59808f4435/

面向对象的前端开发

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值