0
0
GraphqlHow-ToIntermediate · 4 min read

How to Use Query Cost Analysis in GraphQL for Efficient APIs

Use query cost analysis in GraphQL by assigning cost values to fields and calculating the total cost of a query before execution. This helps limit expensive queries by rejecting or throttling those exceeding a set cost threshold.
📐

Syntax

Query cost analysis involves defining a cost function for each field in your GraphQL schema and then calculating the total cost of incoming queries. You typically use middleware or plugins that intercept queries, compute their cost, and enforce limits.

Key parts:

  • cost: Numeric value assigned to each field representing its resource usage.
  • maximumCost: Maximum allowed cost for a query.
  • costAnalysis: Function or plugin that calculates total query cost.
javascript
const costAnalysis = require('graphql-cost-analysis');

const costPlugin = costAnalysis({
  maximumCost: 1000,
  variables: {},
  onComplete: (cost) => {
    console.log('Query cost:', cost);
  },
  createError: (max, actual) =>
    new Error(`Query cost ${actual} exceeds max cost of ${max}`),
});
💻

Example

This example shows how to add query cost analysis middleware to an Apollo Server setup. It calculates the cost of each query and rejects queries that exceed the maximum allowed cost.

javascript
const { ApolloServer, gql } = require('apollo-server');
const costAnalysis = require('graphql-cost-analysis');

const typeDefs = gql`
  type Query {
    books(limit: Int): [Book]
  }
  type Book {
    title: String
    author: String
  }
`;

const resolvers = {
  Query: {
    books: (_, { limit }) => {
      const allBooks = [
        { title: 'Book 1', author: 'Author A' },
        { title: 'Book 2', author: 'Author B' },
      ];
      return limit ? allBooks.slice(0, limit) : allBooks;
    },
  },
};

const costPlugin = costAnalysis({
  maximumCost: 10,
  variables: {},
  onComplete: (cost) => {
    console.log('Query cost:', cost);
  },
  createError: (max, actual) =>
    new Error(`Query cost ${actual} exceeds max cost of ${max}`),
});

const server = new ApolloServer({
  typeDefs,
  resolvers,
  plugins: [costPlugin],
});

server.listen().then(({ url }) => {
  console.log(`Server ready at ${url}`);
});
Output
Server ready at http://localhost:4000/ Query cost: 5
⚠️

Common Pitfalls

Common mistakes when using query cost analysis include:

  • Not assigning cost values to all fields, which can underestimate query cost.
  • Setting the maximumCost too high or too low, causing either too many rejected queries or allowing expensive queries.
  • Ignoring variables in cost calculation, leading to inaccurate cost estimates.
  • Not handling errors properly when cost limits are exceeded, causing unclear API responses.
javascript
/* Wrong: No cost limit set, so expensive queries run unchecked */
const costPluginWrong = costAnalysis({
  maximumCost: Infinity,
});

/* Right: Set a reasonable max cost and handle errors */
const costPluginRight = costAnalysis({
  maximumCost: 1000,
  createError: (max, actual) => new Error(`Query cost ${actual} exceeds max cost of ${max}`),
});
📊

Quick Reference

  • Assign cost values to fields based on resource usage.
  • Use middleware or plugins like graphql-cost-analysis to calculate query cost.
  • Set a maximum cost limit to protect your server.
  • Reject or throttle queries exceeding the cost limit.
  • Log query costs for monitoring and optimization.

Key Takeaways

Assign cost values to GraphQL fields to estimate query resource usage.
Use query cost analysis middleware to calculate and enforce cost limits.
Set a maximum cost threshold to prevent expensive queries from running.
Handle cost limit errors gracefully to inform clients about query rejection.
Monitor query costs to optimize API performance and security.