From 0a02d557b0fc599b921381cce7b5082dd19b7383 Mon Sep 17 00:00:00 2001 From: Idalith Bustos Date: Fri, 20 Sep 2024 16:58:38 -0700 Subject: [PATCH 1/8] edits --- .../en/querying/querying-best-practices.mdx | 63 +++++++++---------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/website/pages/en/querying/querying-best-practices.mdx b/website/pages/en/querying/querying-best-practices.mdx index 32d1415b20fa..a0d7e79f592c 100644 --- a/website/pages/en/querying/querying-best-practices.mdx +++ b/website/pages/en/querying/querying-best-practices.mdx @@ -2,11 +2,9 @@ title: Querying Best Practices --- -The Graph provides a decentralized way to query data from blockchains. +The Graph provides a decentralized way to query data from blockchains via GraphQL API, making it easier to query data with the GraphQL language. -The Graph network's data is exposed through a GraphQL API, making it easier to query data with the GraphQL language. - -This page will guide you through the essential GraphQL language rules and GraphQL queries best practices. +Learn the essential GraphQL language rules and GraphQL queries best practices. --- @@ -71,7 +69,7 @@ GraphQL is a language and set of conventions that transport over HTTP. It means that you can query a GraphQL API using standard `fetch` (natively or via `@whatwg-node/fetch` or `isomorphic-fetch`). -However, as stated in ["Querying from an Application"](/querying/querying-from-an-application), we recommend you to use our `graph-client` that supports unique features such as: +However, as stated in ["Querying from an Application"](/querying/querying-from-an-application), it's recommend to use `graph-client` which supports unique features such as: - Cross-chain Subgraph Handling: Querying from multiple subgraphs in a single query - [Automatic Block Tracking](https://github.com/graphprotocol/graph-client/blob/main/packages/block-tracking/README.md) @@ -104,8 +102,6 @@ main() More GraphQL client alternatives are covered in ["Querying from an Application"](/querying/querying-from-an-application). -Now that we covered the basic rules of GraphQL queries syntax, let's now look at the best practices of GraphQL query writing. - --- ## Best Practices @@ -164,11 +160,11 @@ Doing so brings **many advantages**: - **Variables can be cached** at server-level - **Queries can be statically analyzed by tools** (more on this in the following sections) -**Note: How to include fields conditionally in static queries** +### How to include fields conditionally in static queries -We might want to include the `owner` field only on a particular condition. +You might want to include the `owner` field only on a particular condition. -For this, we can leverage the `@include(if:...)` directive as follows: +For this, you can leverage the `@include(if:...)` directive as follows: ```tsx import { execute } from 'your-favorite-graphql-client' @@ -191,7 +187,7 @@ const result = await execute(query, { }) ``` -Note: The opposite directive is `@skip(if: ...)`. +> Note: The opposite directive is `@skip(if: ...)`. ### Ask for what you want @@ -199,9 +195,10 @@ GraphQL became famous for its "Ask for what you want" tagline. For this reason, there is no way, in GraphQL, to get all available fields without having to list them individually. -When querying GraphQL APIs, always think of querying only the fields that will be actually used. - -A common cause of over-fetching is collections of entities. By default, queries will fetch 100 entities in a collection, which is usually much more than what will actually be used, e.g., for display to the user. Queries should therefore almost always set first explicitly, and make sure they only fetch as many entities as they actually need. This applies not just to top-level collections in a query, but even more so to nested collections of entities. +- When querying GraphQL APIs, always think of querying only the fields that will be actually used. +- A common cause of over-fetching is collections of entities. By default, queries will fetch 100 entities in a collection, which is usually much more than what will actually be used, e.g., for display to the user. +- Queries should always be set first explicitly. + - Make sure queries only fetch as many entities as they actually need. This applies not just to top-level collections in a query, but even more so to nested collections of entities. For example, in the following query: @@ -337,8 +334,8 @@ query { Such repeated fields (`id`, `active`, `status`) bring many issues: -- harder to read for more extensive queries -- when using tools that generate TypeScript types based on queries (_more on that in the last section_), `newDelegate` and `oldDelegate` will result in two distinct inline interfaces. +- Harder to read for more extensive queries +- When using tools that generate TypeScript types based on queries (_more on that in the last section_), `newDelegate` and `oldDelegate` will result in two distinct inline interfaces. A refactored version of the query would be the following: @@ -364,13 +361,13 @@ fragment DelegateItem on Transcoder { } ``` -Using GraphQL `fragment` will improve readability (especially at scale) but also will result in better TypeScript types generation. +Using GraphQL `fragment` will improve readability (especially at scale) and result in better TypeScript types generation. When using the types generation tool, the above query will generate a proper `DelegateItemFragment` type (_see last "Tools" section_). ### GraphQL Fragment do's and don'ts -**Fragment base must be a type** +### Fragment base must be a type A Fragment cannot be based on a non-applicable type, in short, **on type not having fields**: @@ -382,7 +379,7 @@ fragment MyFragment on BigInt { `BigInt` is a **scalar** (native "plain" type) that cannot be used as a fragment's base. -**How to spread a Fragment** +#### How to spread a Fragment Fragments are defined on specific types and should be used accordingly in queries. @@ -411,7 +408,7 @@ fragment VoteItem on Vote { It is not possible to spread a fragment of type `Vote` here. -**Define Fragment as an atomic business unit of data** +#### Define Fragment as an atomic business unit of data GraphQL Fragment must be defined based on their usage. @@ -419,8 +416,8 @@ For most use-case, defining one fragment per type (in the case of repeated field Here is a rule of thumb for using Fragment: -- when fields of the same type are repeated in a query, group them in a Fragment -- when similar but not the same fields are repeated, create multiple fragments, ex: +- When fields of the same type are repeated in a query, group them in a Fragment +- When similar but not the same fields are repeated, create multiple fragments, ex: ```graphql # base fragment (mostly used in listing) @@ -443,7 +440,7 @@ fragment VoteWithPoll on Vote { --- -## The essential tools +## The Essential Tools ### GraphQL web-based explorers @@ -473,11 +470,11 @@ This will allow you to **catch errors without even testing queries** on the play The [GraphQL VSCode extension](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql) is an excellent addition to your development workflow to get: -- syntax highlighting -- autocomplete suggestions -- validation against schema -- snippets -- go to definition for fragments and input types +- Syntax highlighting +- Autocomplete suggestions +- Validation against schema +- Snippets +- Go to definition for fragments and input types If you are using `graphql-eslint`, the [ESLint VSCode extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) is a must-have to visualize errors and warnings inlined in your code correctly. @@ -485,9 +482,9 @@ If you are using `graphql-eslint`, the [ESLint VSCode extension](https://marketp The [JS GraphQL plugin](https://plugins.jetbrains.com/plugin/8097-graphql/) will significantly improve your experience while working with GraphQL by providing: -- syntax highlighting -- autocomplete suggestions -- validation against schema -- snippets +- Syntax highlighting +- Autocomplete suggestions +- Validation against schema +- Snippets -More information on this [WebStorm article](https://blog.jetbrains.com/webstorm/2019/04/featured-plugin-js-graphql/) that showcases all the plugin's main features. +For more information on this topic, check out the [WebStorm article](https://blog.jetbrains.com/webstorm/2019/04/featured-plugin-js-graphql/) which showcases all the plugin's main features. From 9ef5575e5a0e62ab387f96caab60bdf810e3c2d3 Mon Sep 17 00:00:00 2001 From: Idalith <126833353+idalithb@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:20:04 -0700 Subject: [PATCH 2/8] Update website/pages/en/querying/querying-best-practices.mdx --- website/pages/en/querying/querying-best-practices.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/querying/querying-best-practices.mdx b/website/pages/en/querying/querying-best-practices.mdx index a0d7e79f592c..24257724b3dc 100644 --- a/website/pages/en/querying/querying-best-practices.mdx +++ b/website/pages/en/querying/querying-best-practices.mdx @@ -4,7 +4,7 @@ title: Querying Best Practices The Graph provides a decentralized way to query data from blockchains via GraphQL API, making it easier to query data with the GraphQL language. -Learn the essential GraphQL language rules and GraphQL queries best practices. +Learn the essential GraphQL language rules and GraphQL querying best practices. --- From 0793a9172c4dfde16414e69b89472bf785fb3e92 Mon Sep 17 00:00:00 2001 From: Idalith <126833353+idalithb@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:20:17 -0700 Subject: [PATCH 3/8] Update website/pages/en/querying/querying-best-practices.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Benoît Rouleau --- website/pages/en/querying/querying-best-practices.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/querying/querying-best-practices.mdx b/website/pages/en/querying/querying-best-practices.mdx index 24257724b3dc..f883a37b89d9 100644 --- a/website/pages/en/querying/querying-best-practices.mdx +++ b/website/pages/en/querying/querying-best-practices.mdx @@ -2,7 +2,7 @@ title: Querying Best Practices --- -The Graph provides a decentralized way to query data from blockchains via GraphQL API, making it easier to query data with the GraphQL language. +The Graph provides a decentralized way to query data from blockchains via GraphQL APIs, making it easier to query data with the GraphQL language. Learn the essential GraphQL language rules and GraphQL querying best practices. From 43193bc29e92820f2b7eea5dde9cfcab8f7db7d7 Mon Sep 17 00:00:00 2001 From: Idalith <126833353+idalithb@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:20:48 -0700 Subject: [PATCH 4/8] Update website/pages/en/querying/querying-best-practices.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Benoît Rouleau --- website/pages/en/querying/querying-best-practices.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/website/pages/en/querying/querying-best-practices.mdx b/website/pages/en/querying/querying-best-practices.mdx index f883a37b89d9..38585528c5d0 100644 --- a/website/pages/en/querying/querying-best-practices.mdx +++ b/website/pages/en/querying/querying-best-practices.mdx @@ -196,9 +196,7 @@ GraphQL became famous for its "Ask for what you want" tagline. For this reason, there is no way, in GraphQL, to get all available fields without having to list them individually. - When querying GraphQL APIs, always think of querying only the fields that will be actually used. -- A common cause of over-fetching is collections of entities. By default, queries will fetch 100 entities in a collection, which is usually much more than what will actually be used, e.g., for display to the user. -- Queries should always be set first explicitly. - - Make sure queries only fetch as many entities as they actually need. This applies not just to top-level collections in a query, but even more so to nested collections of entities. +- Make sure queries only fetch as many entities as you actually need. By default, queries will fetch 100 entities in a collection, which is usually much more than what will actually be used, e.g., for display to the user. This applies not just to top-level collections in a query, but even more so to nested collections of entities. For example, in the following query: From 7d9abc2ee330466cb5c52b88e5d1eec21d838897 Mon Sep 17 00:00:00 2001 From: Idalith <126833353+idalithb@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:21:03 -0700 Subject: [PATCH 5/8] Update website/pages/en/querying/querying-best-practices.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Benoît Rouleau --- website/pages/en/querying/querying-best-practices.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/querying/querying-best-practices.mdx b/website/pages/en/querying/querying-best-practices.mdx index 38585528c5d0..a8a60921fdb7 100644 --- a/website/pages/en/querying/querying-best-practices.mdx +++ b/website/pages/en/querying/querying-best-practices.mdx @@ -332,7 +332,7 @@ query { Such repeated fields (`id`, `active`, `status`) bring many issues: -- Harder to read for more extensive queries +- More extensive queries become harder to read. - When using tools that generate TypeScript types based on queries (_more on that in the last section_), `newDelegate` and `oldDelegate` will result in two distinct inline interfaces. A refactored version of the query would be the following: From d2247cd8d48c6046991a5ff796f9e2dcb8ca3b96 Mon Sep 17 00:00:00 2001 From: Idalith <126833353+idalithb@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:21:09 -0700 Subject: [PATCH 6/8] Update website/pages/en/querying/querying-best-practices.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Benoît Rouleau --- website/pages/en/querying/querying-best-practices.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/querying/querying-best-practices.mdx b/website/pages/en/querying/querying-best-practices.mdx index a8a60921fdb7..790b1084c90d 100644 --- a/website/pages/en/querying/querying-best-practices.mdx +++ b/website/pages/en/querying/querying-best-practices.mdx @@ -408,7 +408,7 @@ It is not possible to spread a fragment of type `Vote` here. #### Define Fragment as an atomic business unit of data -GraphQL Fragment must be defined based on their usage. +GraphQL `Fragment`s must be defined based on their usage. For most use-case, defining one fragment per type (in the case of repeated fields usage or type generation) is sufficient. From eb2207186193cad5b220371d32f214579ba26e75 Mon Sep 17 00:00:00 2001 From: Idalith <126833353+idalithb@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:21:17 -0700 Subject: [PATCH 7/8] Update website/pages/en/querying/querying-best-practices.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Benoît Rouleau --- website/pages/en/querying/querying-best-practices.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/pages/en/querying/querying-best-practices.mdx b/website/pages/en/querying/querying-best-practices.mdx index 790b1084c90d..21b7cb3758b9 100644 --- a/website/pages/en/querying/querying-best-practices.mdx +++ b/website/pages/en/querying/querying-best-practices.mdx @@ -412,7 +412,7 @@ GraphQL `Fragment`s must be defined based on their usage. For most use-case, defining one fragment per type (in the case of repeated fields usage or type generation) is sufficient. -Here is a rule of thumb for using Fragment: +Here is a rule of thumb for using fragments: - When fields of the same type are repeated in a query, group them in a Fragment - When similar but not the same fields are repeated, create multiple fragments, ex: From 6d67a04b58b443e7d4f0e69d9e02ad6232970688 Mon Sep 17 00:00:00 2001 From: Idalith <126833353+idalithb@users.noreply.github.com> Date: Fri, 20 Sep 2024 17:21:28 -0700 Subject: [PATCH 8/8] Update website/pages/en/querying/querying-best-practices.mdx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Benoît Rouleau --- website/pages/en/querying/querying-best-practices.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/website/pages/en/querying/querying-best-practices.mdx b/website/pages/en/querying/querying-best-practices.mdx index 21b7cb3758b9..5654cf9e23a5 100644 --- a/website/pages/en/querying/querying-best-practices.mdx +++ b/website/pages/en/querying/querying-best-practices.mdx @@ -414,8 +414,8 @@ For most use-case, defining one fragment per type (in the case of repeated field Here is a rule of thumb for using fragments: -- When fields of the same type are repeated in a query, group them in a Fragment -- When similar but not the same fields are repeated, create multiple fragments, ex: +- When fields of the same type are repeated in a query, group them in a `Fragment`. +- When similar but different fields are repeated, create multiple fragments, for instance: ```graphql # base fragment (mostly used in listing)