xclade
GraphQL API

Best Practices

GraphQL best practices and patterns

Best Practices

Use Named Queries

Always name your queries for better debugging and monitoring:

# Good
query GetProductList {
  products { ... }
}

# Bad
query {
  products { ... }
}

Use Fragments for Reusability

Define reusable fragments for common field selections:

fragment ProductBasic on Product {
  id
  title
  handle
  thumbnail
  status
}

query GetProducts {
  products(limit: 10) {
    products {
      ...ProductBasic
    }
  }
}

query GetProduct($id: String!) {
  product(id: $id) {
    ...ProductBasic
    description
    variants {
      id
      title
    }
  }
}

Use Variables for Dynamic Values

Never interpolate values directly into queries:

// Good
const query = gql`
  query GetProduct($id: String!) {
    product(id: $id) { ... }
  }
`;
client.query({ query, variables: { id: productId } });

// Bad - Security risk
const query = gql`
  query {
    product(id: "${productId}") { ... }
  }
`;

Handle Loading and Error States

Always handle loading and error states in your UI:

function ProductList() {
  const { loading, error, data } = useQuery(GET_PRODUCTS);
  
  if (loading) return <Spinner />;
  if (error) return <ErrorMessage error={error} />;
  
  return <ProductGrid products={data.products.products} />;
}

Implement Retry Logic

Implement exponential backoff for rate limit errors:

async function queryWithRetry(query, variables, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await executeQuery(query, variables);
    } catch (error) {
      if (error.extensions?.code === 'RATE_LIMIT_EXCEEDED') {
        const retryAfter = error.extensions.retryAfter || Math.pow(2, attempt);
        await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
        continue;
      }
      throw error;
    }
  }
  throw new Error('Max retries exceeded');
}

Monitor Query Performance

Log slow queries for optimization:

const startTime = Date.now();
const result = await executeQuery(query, variables);
const duration = Date.now() - startTime;

if (duration > 1000) {
  console.warn(`Slow query (${duration}ms):`, query);
}

On this page