graphql_普通英语GraphQL指南
graphql
by Luis Aguilar
路易斯·阿吉拉爾(Luis Aguilar)
普通英語(yǔ)GraphQL指南 (A Guide to GraphQL in Plain English)
您需要了解的最新流行語(yǔ)正在席卷API開(kāi)發(fā)領(lǐng)域。 (All you need to know about the latest buzzword that’s taking the API development scene by storm.)
TL; DR (TL;DR)
GraphQL is a query language and runtime that we can use to build and expose APIs as a strongly-typed schema instead of hundreds of REST endpoints. Your clients see the schema. They write a query for what they want. They send it over and get back exactly the data they asked for and nothing more.
GraphQL是一種查詢(xún)語(yǔ)言和運(yùn)行時(shí),我們可以使用它來(lái)構(gòu)建API并將其顯示為強(qiáng)類(lèi)型架構(gòu),而不是數(shù)百個(gè)REST端點(diǎn)。 您的客戶(hù)看到架構(gòu)。 他們編寫(xiě)查詢(xún)以查找所需內(nèi)容。 他們將其發(fā)送出去,并準(zhǔn)確地取回他們所要求的數(shù)據(jù),僅此而已。
A schema looks like:
模式如下所示:
So, if a client wants a user with an ID of 2, instead of doing a GET /api/v1/users/2, they would rather send a query like this:
因此,如果客戶(hù)端希望一個(gè)ID為2的用戶(hù),而不是執(zhí)行GET /api/v1/users/2 ,他們寧愿發(fā)送如下查詢(xún):
… and get a response like this:
……并得到這樣的回應(yīng):
Why should REST watch its back, and why should you care?
為什么應(yīng)該休息看它的后面,為什么你要在乎?
-
The schema is strongly-typed. The schema dictates that the
idparameter must be an integer. If a client sendsuser(id: “2”)instead, the GraphQL engine will reject the whole query.模式是強(qiáng)類(lèi)型的。 該模式要求
id參數(shù)必須為整數(shù)。 如果客戶(hù)端改為發(fā)送user(id: “2”),則GraphQL引擎將拒絕整個(gè)查詢(xún)。 -
Clients pick what they need. See those braces after the query parameters? That’s how our clients tell which fields they want. Fewer fields = leaner and faster responses.
客戶(hù)選擇他們需要的東西。 查詢(xún)參數(shù)后看到那些花括號(hào)? 這就是我們的客戶(hù)告訴他們想要哪些字段的方式。 更少的字段=更精簡(jiǎn)和更快的響應(yīng)。
-
It’s fast. Fields not picked won’t be processed, meaning less stress on the server.
它很快。 未選擇的字段將不被處理,這將減輕服務(wù)器的壓力。
-
And most importantly, it’s flexible. If a client needs fewer fields from an endpoint, we don’t create a new endpoint or version our whole API exclusively for that need. They can pick whichever fields they need, and that’s free for us.
最重要的是,它很靈活。 如果客戶(hù)端從端點(diǎn)需要的字段較少,我們不會(huì)專(zhuān)門(mén)為此創(chuàng)建新的端點(diǎn)或?yàn)檎麄€(gè)API版本。 他們可以選擇所需的任何字段,這對(duì)我們來(lái)說(shuō)是免費(fèi)的。
And that’s all there is to it, really. No magic is going on. Just a more convenient, flexible, and natural way of building your API.
真的,這就是全部。 沒(méi)有魔術(shù)在繼續(xù)。 這是構(gòu)建API的更方便,靈活,自然的方法。
But what is life without those juicy core concepts and sweet, sweet code examples?
但是,如果沒(méi)有那些多汁的核心概念和甜美,甜美的代碼示例,生活將會(huì)怎樣?
五巨頭 (The Big Five)
Before moving onto the actual fun, there are some concepts we need to have in mind, otherwise everything else won’t make any sense.
在開(kāi)始實(shí)際樂(lè)趣之前,我們需要牢記一些概念,否則其他所有內(nèi)容都將毫無(wú)意義。
Don’t worry—I’ll keep it short.
不用擔(dān)心,我會(huì)盡量簡(jiǎn)短。
詢(xún)問(wèn) (Query)
A member of the schema that reads data.
讀取數(shù)據(jù)的架構(gòu)成員。
突變 (Mutation)
A member of the schema that modifies data (as in create, edit, or delete.)
修改數(shù)據(jù)(如創(chuàng)建,編輯或刪除)的架構(gòu)成員。
架構(gòu)圖 (Schema)
A single-rooted tree with two primary nodes: one for queries, and another for mutations.
具有兩個(gè)主節(jié)點(diǎn)的單根樹(shù):一個(gè)用于查詢(xún),另一個(gè)用于突變。
類(lèi)型 (Type)
The shape of everything composing the schema. The data returned by a query, the fields of that data, the parameters taken by a mutation, queries, and mutations themselves—everything has a type.
組成架構(gòu)的所有事物的形狀。 查詢(xún)返回的數(shù)據(jù),該數(shù)據(jù)的字段,突變所采用的參數(shù),查詢(xún)以及突變本身—每種類(lèi)型都有。
Types are composed of fields which also have a type.
類(lèi)型由也具有類(lèi)型的字段組成。
Both the query and mutation initial nodes are of type Query and Mutation respectively. These have more fields, users and user, and their type can also have more fields! That’s how you structure your API data into a queryable tree.
query和mutation初始節(jié)點(diǎn)的類(lèi)型分別為Query和Mutation 。 這些具有更多字段, users和user ,并且它們的類(lèi)型也可以具有更多字段! 這就是您將API數(shù)據(jù)構(gòu)造為可查詢(xún)樹(shù)的方式。
解析器 (Resolver)
The actual piece that connects your code to your schema. Resolvers are actual functions that resolve the value of a single field in a type. The following is a very, very barebones pseudo example of how it works—don’t mind it too much.
將代碼連接到架構(gòu)的實(shí)際部分。 解析器是用于解析類(lèi)型中單個(gè)字段值的實(shí)際函數(shù)。 以下是其工作方式的非常非常準(zhǔn)的偽示例—不必太在意。
Easy, right? Well, that’s it for theory, time for some code!
容易吧? 好了,理論上就是這樣,花些時(shí)間編寫(xiě)代碼!
完全原始且未過(guò)度使用的代碼示例 (A Totally Original and Not Overused Code Example)
Tired of the classic user model code example? Me neither! Okay, it might be dull and uninteresting, but it serves well to illustrate the previous concepts, so let’s stick to it. By the end, we’ll have an API clients will be able to query for users, roles, and create new users.
厭倦了經(jīng)典的用戶(hù)模型代碼示例? 我也不! 好的,它可能很枯燥和無(wú)趣,但是可以很好地說(shuō)明以前的概念,所以讓我們堅(jiān)持下去。 到最后,我們將擁有一個(gè)API客戶(hù)端,這些客戶(hù)端將能夠查詢(xún)用戶(hù),角色并創(chuàng)建新用戶(hù)。
1.創(chuàng)建服務(wù)器 (1. Create a Server)
As already mentioned, GraphQL is a language, and a runtime—we still have to put it somewhere. For this example, it will live in an Express server.
如前所述,GraphQL是一種語(yǔ)言, 也是一種運(yùn)行時(shí),我們?nèi)匀槐仨殞⑵浞旁谀硞€(gè)地方。 對(duì)于此示例,它將駐留在Express服務(wù)器中。
So let’s get started:
因此,讓我們開(kāi)始吧:
- Create a new folder.
新建一個(gè)文件夾。
-
Open a terminal and
cdto your folder.打開(kāi)一個(gè)終端并
cd到您的文件夾。 -
Run
npm init && touch server.js運(yùn)行
npm init && touch server.js -
Run
npm i express --saveto, well, install ExpressJS.運(yùn)行
npm i express --save到ExpressJS。 -
Throw this into
server.js:扔到
server.js:
-
Run the server with
node server.js使用
node server.js運(yùn)行服務(wù)器
And so we have a home for our GraphQL API.
因此,我們有了GraphQL API的家。
2.添加一小撮GraphQL (2. Add a Pinch of GraphQL)
As simple as:
簡(jiǎn)單如:
-
Run
npm i graphql graphql-express --save運(yùn)行
npm i graphql graphql-express --save -
Edit
server.jslike this:像這樣編輯
server.js:
And this is why it was essential to review the concepts before moving onto the code. This simple Hello World app already has a lot going on, but we can at least get an idea.
這就是為什么在移入代碼之前必須先復(fù)習(xí)這些概念的原因。 這個(gè)簡(jiǎn)單的Hello World應(yīng)用程序已經(jīng)進(jìn)行了很多工作,但是我們至少可以了解一下。
Don’t worry, here’s the annotated version:
別擔(dān)心,這是帶注釋的版本:
Wait, are we hardcoding our schema using a huge magic string? Don’t panic— we’ll get to that later.
等等,我們是否使用巨大的魔術(shù)字符串對(duì)模式進(jìn)行硬編碼? 不要驚慌,我們稍后再討論。
Okay, time to fire up Postman and send some queries to our GraphQL API!
好的,是時(shí)候啟動(dòng)Postman并將一些查詢(xún)發(fā)送到我們的GraphQL API了!
Heh, just kidding…
嘿,開(kāi)玩笑...
At line 46 we enabled GraphiQL (pronounced “graphical,”) a built-in fully-featured IDE for writing queries. Now, close Postman and go to localhost:4000/graphql in your browser of preference.
在第46行,我們啟用了GraphiQL(發(fā)音為“ graphical” ),這是一個(gè)內(nèi)置的功能齊全的IDE,用于編寫(xiě)查詢(xún)。 現(xiàn)在,關(guān)閉Postman并在您偏好的瀏覽器中轉(zhuǎn)到localhost:4000/graphql 。
What can you do with this? Well, here are some things you can try:
你能做什么呢? 好了,您可以嘗試以下操作:
-
View schema. To the right, select the
Queryroot type to see its fields, return types, documentation, etc.查看架構(gòu)。 在右側(cè),選擇
Query根類(lèi)型以查看其字段,返回類(lèi)型,文檔等。 -
Write queries. To the left, type the following query, and notice how the editor shows autocompletion and documentation as you go:
編寫(xiě)查詢(xún)。 在左側(cè),鍵入以下查詢(xún),并注意編輯器在顯示過(guò)程中如何顯示自動(dòng)完成和文檔:
-
Test queries. If your query is valid, hit that play button at the top and see the results in the middle pane.
測(cè)試查詢(xún)。 如果查詢(xún)有效,請(qǐng)點(diǎn)擊頂部的播放按鈕,然后在中間窗格中查看結(jié)果。
But what about clients? They can use GraphiQL (or a similar tool—there are tons) to build and test their queries. Then send them over using a GraphQL client like Apollo Boost—as easy as copying and pasting!
但是客戶(hù)呢? 他們可以使用Graph i QL(或類(lèi)似的工具-有很多)來(lái)構(gòu)建和測(cè)試他們的查詢(xún)。 然后使用像Apollo Boost這樣的GraphQL客戶(hù)端將它們發(fā)送過(guò)來(lái),就像復(fù)制和粘貼一樣簡(jiǎn)單!
3.添加查詢(xún)以列出用戶(hù) (3. Add a Query to List Users)
All right, Hello World is fine and all, but we want to do more than greeting people. Let’s add a new User type, and replace hello with users which will return all users from a dummy repository.
好的,Hello World很好,但是,我們要做的不僅僅是問(wèn)候別人。 讓我們添加一個(gè)新的User類(lèi)型,然后用users替換hello ,這將返回虛擬存儲(chǔ)庫(kù)中的所有用戶(hù)。
-
Edit
server.jslike this:像這樣編輯
server.js:
-
Grab the
user-repository.jsfile from here and put it in your local directory.從此處獲取
user-repository.js文件,并將其放在您的本地目錄中。 -
Restart your server and refresh the GraphiQL editor.
重新啟動(dòng)服務(wù)器并刷新Graph i QL編輯器。
-
In your query, replace
helloforusers { id, login }and hit play.在您的查詢(xún)中,為
users { id, login }替換hellousers { id, login }然后點(diǎn)擊播放。 -
Profit.
利潤(rùn)。
Annotated:
注釋:
4.添加查詢(xún)以按ID獲取單個(gè)用戶(hù) (4. Add a Query to Get a Single User By ID)
By now, you might be asking: if queries are also fields of a type, why not call them fields? What makes them different?
現(xiàn)在,您可能會(huì)問(wèn):如果查詢(xún)也是一種類(lèi)型的字段,為什么不將它們稱(chēng)為字段? 是什么使它們與眾不同?
Queries can take parameters and use a resolver.
查詢(xún)可以采用參數(shù)并使用解析器。
The easiest way to see it is to compare it to OOP classes. While classes have fields and functions, GraphQL types have fields and queries.
最簡(jiǎn)單的查看方法是將其與OOP類(lèi)進(jìn)行比較。 雖然類(lèi)具有字段和函數(shù),但是GraphQL類(lèi)型具有字段和查詢(xún)。
-
Edit
server.jswith:使用以下命令編輯
server.js:
Again, no magic.
再次,沒(méi)有魔術(shù)。
We’re saying the user query takes an id parameter, and that’s what its resolver function will take. Oh, also notice the ! sign meaning the parameter is required—GraphQL will make sure it is provided.
我們說(shuō)的是user查詢(xún)使用id參數(shù),這就是它的解析器函數(shù)所采用的參數(shù)。 呵呵,還注意了! 符號(hào)表示該參數(shù)是必需的-GraphQL將確保已提供該參數(shù)。
5.用手動(dòng)定義替換Schema Builder (5. Replace Schema Builder with Manual Definitions)
Remember how we called out that huge magic string we used to define our schema? Well, it’s time to fix that.
還記得我們?nèi)绾握{(diào)出用來(lái)定義架構(gòu)的巨大魔術(shù)字符串嗎? 好了,是時(shí)候解決這個(gè)問(wèn)題了。
Okay, in a real-world app, you would put your schema in separate *.graphql files. Then you can add syntax highlighting and code completion plugins to your code editor. However, manual definitions offers a better integration with the rest of our code. Check out this article for more info.
好的,在真實(shí)世界的應(yīng)用程序中,您可以將架構(gòu)放在單獨(dú)的*.graphql文件中。 然后,您可以將語(yǔ)法高亮和代碼完成插件添加到代碼編輯器中。 但是,手動(dòng)定義可以與我們的其余代碼更好地集成。 查看這篇文章以獲取更多信息。
For this step, we’ll use the specialized classes and helpers provided by GraphQL:
在此步驟中,我們將使用GraphQL提供的專(zhuān)用類(lèi)和幫助器:
Done? Okay, now annotated:
做完了嗎 好的,現(xiàn)在注釋:
This way we can put our type definitions in separate files to better organize our server code!
這樣,我們可以將類(lèi)型定義放在單獨(dú)的文件中,以更好地組織服務(wù)器代碼!
As pointed out in the example, in this notation, the resolver function takes the following parameters:
如示例中指出的那樣,在這種表示法中,resolver函數(shù)采用以下參數(shù):
-
root—the resolved parent object, in this case the user.root-解析的父對(duì)象,在這種情況下,用戶(hù)。 -
args—arguments passed by the query.args-參數(shù)被查詢(xún)過(guò)。 -
context,info—out of the scope of this guide.context,info-在本指南的范圍之外。
6.添加用于獲取用戶(hù)角色的子查詢(xún) (6. Add a Sub-query for Fetching User Roles)
So far, we’ve learned to define basic queries. Time to turn it up a notch! Let’s add a new field to the User type for its assigned roles. In a traditional architecture, we’d be tempted to create a new query like userRoles(userId: Int!): Role and call it a day. But that’s not how things work in GraphQL!
到目前為止,我們已經(jīng)學(xué)會(huì)了定義基本查詢(xún)。 是時(shí)候提高它了! 讓我們?cè)凇?User類(lèi)型”中為其分配的角色添加一個(gè)新字段。 在傳統(tǒng)的體系結(jié)構(gòu)中,我們很想創(chuàng)建一個(gè)新的查詢(xún),例如userRoles(userId: Int!): Role并稱(chēng)之為一天。 但這不是GraphQL的工作原理!
We have to think in graphs.
我們必須考慮圖表 。
In the language of graphs, to get the roles of a user we’d send a query like this:
用圖的語(yǔ)言,要獲得用戶(hù)的角色,我們將發(fā)送如下查詢(xún):
… and get a JSON result like this:
…并獲得如下的JSON結(jié)果:
Makes sense, right? Let’s go ahead and modify the schema.
有道理吧? 讓我們繼續(xù)修改模式。
-
Edit
server.jswith:使用以下命令編輯
server.js:
There—we can fetch user roles now. Notice how we used the User instance passed as the first parameter to the resolver to get the ID from the parent resolved user.
在那里-我們現(xiàn)在可以獲取用戶(hù)角色。 請(qǐng)注意,我們?nèi)绾问褂米鳛榈谝粋€(gè)參數(shù)傳遞給解析器的User實(shí)例從父解析用戶(hù)獲取ID。
The advantage of subqueries? GraphQL won’t resolve the roles field unless it’s selected in the query.
子查詢(xún)的優(yōu)勢(shì)? 除非在查詢(xún)中選擇GraphQL,否則GraphQL不會(huì)解析roles字段。
Did you spot the pitfall with the last bit of code?
您是否發(fā)現(xiàn)了最后一部分代碼的隱患?
If we query 100 users and their roles, the roles resolver function will execute a hundred times. Then, let’s say each user has 10 roles and each role has a sub-query field. That query will execute 100 * 10 times.
如果我們查詢(xún)100個(gè)用戶(hù)及其角色,則roles解析器功能將執(zhí)行一百次。 然后,假設(shè)每個(gè)用戶(hù)有10個(gè)角色,每個(gè)角色都有一個(gè)子查詢(xún)字段。 該查詢(xún)將執(zhí)行100 * 10次。
This is called The N + 1 Problem.
這稱(chēng)為N + 1問(wèn)題 。
Finding out how to fix that is your homework! But it’s dangerous to go alone, so take this:
找出解決方法,這是您的作業(yè)! 但是獨(dú)自一人走是危險(xiǎn)的,因此請(qǐng)采取以下措施:
Avoiding n+1 requests in GraphQL, including within subscriptionsNote: this article will not make much sense unless you know the basics of GraphQL, an awesome technology we use at…medium.com
避免在GraphQL中出現(xiàn)n + 1個(gè)請(qǐng)求,包括在訂閱中。 注意:除非您了解GraphQL的基礎(chǔ)知識(shí),否則本文將沒(méi)有多大意義,GraphQL是我們?cè)凇?/em> medium.com上使用的一種很棒的技術(shù)
7.添加一個(gè)變體來(lái)創(chuàng)建一個(gè)新用戶(hù) (7. Add a Mutation to Create a New User)
As mentioned before, mutations are how we change data in our schema. If we want to create, edit, or delete a user account, we’ll need a mutation for that.
如前所述, 變異是我們更改架構(gòu)數(shù)據(jù)的方式。 如果我們要?jiǎng)?chuàng)建,編輯或刪除用戶(hù)帳戶(hù),則需要對(duì)其進(jìn)行更改。
Mutations are defined almost exactly the same as a query, and often return the affected data. So the only difference between them is merely logical?
定義的突變與查詢(xún)幾乎完全相同,并且通常返回受影響的數(shù)據(jù)。 因此,它們之間的唯一區(qū)別僅僅是合乎邏輯的嗎?
Exactly.
究竟。
As mentioned before, queries can also take parameters. They only return data.
如前所述,查詢(xún)也可以采用參數(shù)。 它們僅返回?cái)?shù)據(jù)。
-
Edit
server.jswith:使用以下命令編輯
server.js:
-
Send the following query from GraphiQL:
從Graph i QL發(fā)送以下查詢(xún):
-
Profit.
利潤(rùn)。
結(jié)論 (Conclusion)
So, hopefully, the basics of GraphQL are clear: setting up a server, creating a schema (in plain and complex notation) with types, queries, and mutations. I used quite a basic example. Hopefully it served well for illustrating every concept unobtrusively.
因此,希望GraphQL的基本知識(shí)很清楚:設(shè)置服務(wù)器,使用類(lèi)型,查詢(xún)和變異創(chuàng)建模式(以簡(jiǎn)單和復(fù)雜的符號(hào)表示)。 我用了一個(gè)很基本的例子。 希望它能很好地說(shuō)明每個(gè)概念。
From this point onwards, it’s up to you to expand the example with more stuff. Or you can create a completely new codebase for another use case.
從現(xiàn)在開(kāi)始,由您自己來(lái)擴(kuò)展更多內(nèi)容的示例。 或者,您可以為另一個(gè)用例創(chuàng)建一個(gè)全新的代碼庫(kù)。
To get you going, here are a few things you can try out:
為了助您一臂之力,您可以嘗試以下一些操作:
- Solving the N+1 problem by implementing data loaders.
通過(guò)實(shí)現(xiàn)數(shù)據(jù)加載器解決N + 1問(wèn)題。
- Create mutations for validating user credentials, managing user roles, and more.
創(chuàng)建用于驗(yàn)證用戶(hù)憑據(jù),管理用戶(hù)角色等的變體。
- Add an actual database to feed your resolvers (MySQL, SQLite, etc.)
添加實(shí)際的數(shù)據(jù)庫(kù)以供解析器使用(MySQL,SQLite等)
- Use an authentication backend like OAuth to validate users.
使用OAuth之類(lèi)的身份驗(yàn)證后端來(lái)驗(yàn)證用戶(hù)。
- Create a simple client app that uses the Apollo Boost client to connect to your server.
創(chuàng)建一個(gè)使用Apollo Boost客戶(hù)端連接到服務(wù)器的簡(jiǎn)單客戶(hù)端應(yīng)用程序。
- Rebuild the example with TypeScript.
用TypeScript重建示例。
Possibilities are endless!
可能性是無(wú)止境的!
獲取源代碼 (Get the Source Code)
The entire example is hosted in GitHub. Browse through the tags to see a gradual progression of the code.
整個(gè)示例托管在GitHub中。 瀏覽標(biāo)簽以查看代碼的逐步進(jìn)展。
ldiego08/workshops-graphqlGitHub is where people build software. More than 28 million people use GitHub to discover, fork, and contribute to over…github.com
ldiego08 / workshops-graphql 人們可以在GitHub上構(gòu)建軟件。 超過(guò)2千8百萬(wàn)的人使用GitHub來(lái)發(fā)現(xiàn),發(fā)掘和貢獻(xiàn)超過(guò) github.com
Got questions, comments, or anything you’d like to share? Find me on Twitter as @ldiego08. Also, don’t forget to ?, share, and follow if this post was helpful!
有問(wèn)題,評(píng)論或您想分享的任何內(nèi)容? 在Twitter上以@ ldiego08找到我。 此外,如果這篇文章對(duì)您有幫助,請(qǐng)不要忘記分享,關(guān)注!
Luis Aguilar (@ldiego08) | TwitterSan José, Costa Rica — Writer of sci-fi, software dev @skillshare. twitter.com
路易斯·阿吉拉(Luis Aguilar)(@ ldiego08)| Twitter 哥斯達(dá)黎加的SanJosé,科幻作家,軟件開(kāi)發(fā)人員@skillshare。 twitter.com
翻譯自: https://www.freecodecamp.org/news/a-beginners-guide-to-graphql-60e43b0a41f5/
graphql
總結(jié)
以上是生活随笔為你收集整理的graphql_普通英语GraphQL指南的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: NEC Programming Cont
- 下一篇: Educational Codeforc