Setting the file. One moment.
Subchapter 10.3
references/queries.mdMarkdown8 KBView on GitHub
This reference covers patterns for writing effective GraphQL queries.
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}Components:
query - Operation typeGetUser - Operation name($id: ID!) - Variable definitionsuser(id: $id) - Field with argument{ id name email } - Selection setquery GetDashboardData($userId: ID!) {
user(id: $userId) {
id
name
}
notifications(first: 5) {
id
message
}
stats {
totalPosts
totalComments
}
}query GetUserWithPosts($userId: ID!) {
user(id: $userId) {
id
name
posts(first: 10) {
edges {
node {
id
title
comments(first: 3) {
edges {
node {
id
body
}
}
}
}
}
}
}
}# For a user card component
query GetUserCard($id: ID!) {
user(id: $id) {
id
name
avatarUrl
# Don't request email, bio, etc. if not displayed
}
}Include id for any type you might cache or refetch:
query GetPost($id: ID!) {
post(id: $id) {
id # Always include for caching
title
author {
id # Include for author cache entry
name
}
}
}For paginated data, request what you need:
query GetUserPosts($userId: ID!, $first: Int!, $after: String) {
user(id: $userId) {
id
posts(first: $first, after: $after) {
edges {
node {
id
title
excerpt
}
cursor # Only if implementing infinite scroll
}
pageInfo {
hasNextPage
endCursor
}
totalCount # Only if displaying total
}
}
}Rename fields in the response:
query GetUserNames($id: ID!) {
user(id: $id) {
userId: id
displayName: name
}
}
# Response: { user: { userId: "123", displayName: "John" } }query GetMultipleUsers {
admin: user(id: "1") {
id
name
}
moderator: user(id: "2") {
id
name
}
currentUser: user(id: "3") {
id
name
}
}query GetPostsByStatus($userId: ID!) {
user(id: $userId) {
id
publishedPosts: posts(status: PUBLISHED, first: 5) {
edges {
node {
id
title
}
}
}
draftPosts: posts(status: DRAFT, first: 5) {
edges {
node {
id
title
}
}
}
}
}Include field only if condition is true:
query GetUser($id: ID!, $includeEmail: Boolean!) {
user(id: $id) {
id
name
email @include(if: $includeEmail)
}
}
# Variables: { id: "123", includeEmail: true }
# Returns email field
# Variables: { id: "123", includeEmail: false }
# Does not return email fieldSkip field if condition is true:
query GetPost($id: ID!, $isPreview: Boolean!) {
post(id: $id) {
id
title
content @skip(if: $isPreview)
excerpt
}
}query GetUser($id: ID!, $expanded: Boolean!) {
user(id: $id) {
id
name
...UserDetails @include(if: $expanded)
}
}
fragment UserDetails on User {
bio
website
socialLinks {
platform
url
}
}query GetPost($id: ID!, $showComments: Boolean!, $hideAuthor: Boolean!) {
post(id: $id) {
id
title
author @skip(if: $hideAuthor) {
id
name
}
comments(first: 10) @include(if: $showComments) {
edges {
node {
id
body
}
}
}
}
}| Purpose | Pattern | Examples |
|---|---|---|
| Fetch single item | Get{Type} | GetUser, GetPost |
| Fetch list | List{Types} | ListUsers, ListPosts |
| Search | Search{Types} | SearchUsers, SearchProducts |
| Fetch for specific UI | Get{Feature}Data | GetDashboardData, GetProfilePage |
query GetUserProfile($id: ID!) { ... }
query ListRecentPosts($first: Int!) { ... }
query SearchProducts($query: String!) { ... }
query GetOrderDetails($orderId: ID!) { ... }
query GetHomeFeed($userId: ID!) { ... }# Avoid
query Data { ... }
query Query1 { ... }
query FetchStuff { ... }
# Prefer
query GetCurrentUser { ... }
query ListActiveProjects { ... }
query SearchCustomers($query: String!) { ... }src/
graphql/
queries/
GetUser.graphql
ListPosts.graphql
SearchProducts.graphql# GetUser.graphql
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}src/
components/
UserProfile/
UserProfile.tsx
UserProfile.graphql
UserProfile.test.tsx// With graphql-tag
import { gql } from "@apollo/client";
export const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
}
}
`;
// With .graphql files (requires loader)
import { GetUserDocument } from "./UserProfile.generated";Only request fields used by your component:
# For a list view - minimal fields
query ListPostsForIndex {
posts(first: 20) {
edges {
node {
id
title
excerpt
author { name }
}
}
}
}
# For detail view - more fields
query GetPostDetail($id: ID!) {
post(id: $id) {
id
title
content
publishedAt
author {
id
name
bio
avatarUrl
}
comments(first: 10) { ... }
}
}Never fetch unbounded lists:
# Avoid
query GetAllPosts {
posts {
# Could return thousands
id
title
}
}
# Prefer
query GetPosts($first: Int = 20, $after: String) {
posts(first: $first, after: $after) {
edges {
node {
id
title
}
}
pageInfo {
hasNextPage
endCursor
}
}
}Fetch related data in one request:
# Instead of multiple queries
query GetDashboard($userId: ID!) {
user(id: $userId) {
id
name
}
recentPosts: posts(first: 5, orderBy: { field: CREATED_AT, direction: DESC }) {
edges {
node {
id
title
}
}
}
notifications(first: 10, unreadOnly: true) {
edges {
node {
id
message
}
}
}
}query GetPostsWithAuthors {
posts(first: 10) {
edges {
node {
id
title
author {
...AuthorInfo
}
}
}
}
featuredPost {
id
title
author {
...AuthorInfo
}
}
}
fragment AuthorInfo on User {
id
name
avatarUrl
}