-
Notifications
You must be signed in to change notification settings - Fork 151
Updating Best Practices #959
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
||
--- | ||
|
||
## Querying a GraphQL API | ||
|
||
### The Anatomy of a GraphQL Query | ||
|
||
Unlike REST API, a GraphQL API is built upon a Schema that defines which queries can be performed. | ||
> GraphQL queries use GraphQL language, which is defined in the [GraphQL specification](https://spec.graphql.org/). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
> GraphQL queries use GraphQL language, which is defined in the [GraphQL specification](https://spec.graphql.org/). | |
> GraphQL queries use the GraphQL language, which is defined in the [GraphQL specification](https://spec.graphql.org/). |
@@ -25,7 +25,7 @@ query GetToken($id: ID!) { | |||
} | |||
``` | |||
|
|||
which will return the following predictable JSON response (_when passing the proper `$id` variable value_): | |||
The expected response will return a predictable JSON response (when passing the proper `$id` variable value): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"response" is repeated, the original read better IMO.
|
||
> Note: Failing to follow these rules will result in an error from The Graph API. | ||
1. Each `queryName` must only be used once per operation. | ||
2. Each `field` must be used only once in a selection (you cannot query `id` twice under `token`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. Each `field` must be used only once in a selection (you cannot query `id` twice under `token`) | |
2. Each `field` must be used only once in a selection (you cannot query `id` twice under `token`). |
3. Complex types require selection of sub-fields. | ||
- For example, some `fields' or queries (like `tokens`) return complex types which will require a selection of sub-field. Not providing a selection when expected or providing one when not expected will raise an error, such as `id`. To know a field type, please refer to [Graph Explorer](/subgraphs/explorer/). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3. Complex types require selection of sub-fields. | |
- For example, some `fields' or queries (like `tokens`) return complex types which will require a selection of sub-field. Not providing a selection when expected or providing one when not expected will raise an error, such as `id`. To know a field type, please refer to [Graph Explorer](/subgraphs/explorer/). | |
3. Complex types require a selection of sub-fields. | |
- For example, some `fields' or queries (like `tokens`) return complex types which will require a selection of sub-fields. Not providing a selection when expected or providing one when not expected will raise an error, such as `id`. To know a field type, please refer to [Graph Explorer](/subgraphs/explorer/). |
|
||
A common (bad) practice is to dynamically build query strings as follows: | ||
A common bad practice is to dynamically build a query strings as follows: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A common bad practice is to dynamically build a query strings as follows: | |
A common bad practice is to dynamically build query strings as follows: |
or
A common bad practice is to dynamically build a query strings as follows: | |
A common bad practice is to dynamically build a query string as follows: |
- The full query is harder to understand | ||
- Developers are responsible for safely sanitizing the string interpolation | ||
- Not sending the values of the variables as part of the request can block server-side caching | ||
- It prevents tools from statically analyzing the query (ex: Linter, or type generations tools) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- The full query is harder to understand | |
- Developers are responsible for safely sanitizing the string interpolation | |
- Not sending the values of the variables as part of the request can block server-side caching | |
- It prevents tools from statically analyzing the query (ex: Linter, or type generations tools) | |
- The full query is harder to understand. | |
- Developers are responsible for safely sanitizing the string interpolation. | |
- Not sending the values of the variables as part of the request can block server-side caching. | |
- It prevents tools from statically analyzing the query (e.g. linters or type generation tools). |
- Queries are easier to read, manage, and debug | ||
- Variable sanitization is handled by the GraphQL server The GraphQL | ||
- Variables can be cached at server-level | ||
- Queries can be statically analyzed by tools (see [GraphQL Essential Tools](/subgraphs/querying/best-practices/#graphql-essential-tools-guides)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Queries are easier to read, manage, and debug | |
- Variable sanitization is handled by the GraphQL server The GraphQL | |
- Variables can be cached at server-level | |
- Queries can be statically analyzed by tools (see [GraphQL Essential Tools](/subgraphs/querying/best-practices/#graphql-essential-tools-guides)) | |
- Queries are easier to read, manage, and debug. | |
- Variable sanitization is handled by the GraphQL server. | |
- Variables can be cached at the server level. | |
- Queries can be statically analyzed by tools (see [GraphQL Essential Tools](/subgraphs/querying/best-practices/#graphql-essential-tools-guides)). |
|
||
For this reason, there is no way, in GraphQL, to get all available fields without having to list them individually. | ||
GraphQL is known for it's "Ask for what you want” tagline, which is why it requires explicitly listing each field you want. There's no built-in way to fetch all available fields automatically. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GraphQL is known for it's "Ask for what you want” tagline, which is why it requires explicitly listing each field you want. There's no built-in way to fetch all available fields automatically. | |
GraphQL is known for its "Ask for what you want” tagline, which is why it requires explicitly listing each field you want. There's no built-in way to fetch all available fields automatically. |
@@ -304,9 +301,9 @@ query GetTokensandCounters { | |||
const { result: { tokens, counters } } = execute(query) | |||
``` | |||
|
|||
This approach will **improve the overall performance** by reducing the time spent on the network (saves you a round trip to the API) and will provide a **more concise implementation**. | |||
Sending multiple queries in the same GraphQL request **improves the overall performance** by reducing the time spent on the network (saves you a round trip to the API) and will provide a **more concise implementation**. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sending multiple queries in the same GraphQL request **improves the overall performance** by reducing the time spent on the network (saves you a round trip to the API) and will provide a **more concise implementation**. | |
Sending multiple queries in the same GraphQL request **improves the overall performance** by reducing the time spent on the network (saves you a round trip to the API) and provides a **more concise implementation**. |
|
||
A Fragment cannot be based on a non-applicable type, in short, **on type not having fields**: | ||
1. Fragments cannot be based on a non-applicable types (on type not having fields) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Fragments cannot be based on a non-applicable types (on type not having fields) | |
1. Fragments cannot be based on non-applicable types (types without fields). |
(not 100% sure that's the original meaning)
|
||
A Fragment cannot be based on a non-applicable type, in short, **on type not having fields**: | ||
1. Fragments cannot be based on a non-applicable types (on type not having fields) | ||
2. `BigInt` cannot be used as a fragment's base because it's a **scalar** (native "plain" type) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. `BigInt` cannot be used as a fragment's base because it's a **scalar** (native "plain" type) | |
2. `BigInt` cannot be used as a fragment's base because it's a **scalar** (native "plain" type). |
|
||
GraphQL `Fragment`s must be defined based on their usage. | ||
### How-to Define `Fragment` as an Atomic Business Unit of Data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
### How-to Define `Fragment` as an Atomic Business Unit of Data | |
### How to Define `Fragment` as an Atomic Business Unit of Data |
|
||
For most use-case, defining one fragment per type (in the case of repeated fields usage or type generation) is sufficient. | ||
> For most use-case, defining one fragment per type (in the case of repeated fields usage or type generation) is enough. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
> For most use-case, defining one fragment per type (in the case of repeated fields usage or type generation) is enough. | |
> For most use-cases, defining one fragment per type (in the case of repeated fields usage or type generation) is enough. |
|
||
The [GraphQL VSCode extension](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql) is an excellent addition to your development workflow to get: | ||
Install the [GraphQL VSCode extension](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql) to unlock: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Install the [GraphQL VSCode extension](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql) to unlock: | |
Install the [GraphQL VS Code extension](https://marketplace.visualstudio.com/items?itemName=GraphQL.vscode-graphql) to unlock: |
|
||
- 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. | ||
If you are using `graphql-eslint`, use the [ESLint VSCode extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) to visualize errors and warnings inlined in your code correctly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are using `graphql-eslint`, use the [ESLint VSCode extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) to visualize errors and warnings inlined in your code correctly. | |
If you are using `graphql-eslint`, use the [ESLint VS Code extension](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) to visualize errors and warnings inlined in your code correctly. |
|
||
**WebStorm/Intellij and GraphQL** | ||
2. WebStorm/Intellij and GraphQL\*\* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2. WebStorm/Intellij and GraphQL\*\* | |
2. WebStorm/Intellij and GraphQL |
|
||
The [JS GraphQL plugin](https://plugins.jetbrains.com/plugin/8097-graphql/) will significantly improve your experience while working with GraphQL by providing: | ||
Install the [JS GraphQL plugin](https://plugins.jetbrains.com/plugin/8097-graphql/). It significantly improves your experience while working with GraphQL by providing: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Install the [JS GraphQL plugin](https://plugins.jetbrains.com/plugin/8097-graphql/). It significantly improves your experience while working with GraphQL by providing: | |
Install the [JS GraphQL plugin](https://plugins.jetbrains.com/plugin/8097-graphql/). It significantly improves the experience of working with GraphQL by providing: |
No description provided.