GraphQL vs REST: Which One Should You Choose for Your API?

Learn how to query your API with GraphQL using practical examples of queries, mutations, variables, fragments, and aliases so clients can fetch exactly the data they need from the Pet Store API in a single flexible endpoint.

TRY NANO BANANA FOR FREE

GraphQL vs REST: Which One Should You Choose for Your API?

TRY NANO BANANA FOR FREE
Contents

Choosing between GraphQL and REST impacts your API's flexibility and performance. Both have merits, but they suit different scenarios. Understanding the differences helps you choose wisely.

Fundamental Differences

REST and GraphQL take different approaches to data fetching.

REST uses multiple endpoints. Each endpoint returns a fixed data structure. To get related data, you call multiple endpoints:

GET /api/pets/123
GET /api/pets/123/orders
GET /api/pets/123/vet-records

GraphQL uses a single endpoint. Clients specify exactly what data they need. One request fetches everything:

query {
  pet(id: "123") {
    name
    breed
    orders {
      id
      total
    }
    vetRecords {
      date
      notes
    }
  }
}

Over-fetching and Under-fetching

REST often suffers from two problems.

Over-fetching returns more data than needed. A list endpoint returns 20 fields when you only need 3. This wastes bandwidth and slows applications.

Under-fetching returns too little. One endpoint doesn't include related data. You make multiple requests to get everything. This increases latency.

GraphQL solves both. Clients specify exactly what they need. Nothing more, nothing less.

Example: Fetching Pet Data

REST approach:

// Fetch pet details
const petResponse = await fetch('/api/pets/123');
const pet = await petResponse.json();

// Fetch pet's orders (separate request)
const ordersResponse = await fetch('/api/pets/123/orders');
const orders = await ordersResponse.json();

// Fetch pet's category
const categoryResponse = await fetch(`/api/categories/${pet.categoryId}`);
const category = await categoryResponse.json();

// Combine data
const fullData = {
  ...pet,
  category,
  orders
};

Three requests, one of them dependent on the first. More requests mean more waiting.

GraphQL approach:

const query = `
  query GetPetData($petId: ID!) {
    pet(id: $petId) {
      name
      status
      category {
        name
      }
      orders {
        id
        total
        createdAt
      }
    }
  }
`;

const result = await fetch('https://api.petstoreapi.com/v1/graphql', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    query,
    variables: { petId: '123' }
  })
});

const { data } = await result.json();

One request fetches everything. Exactly what you need. No extra fields.

When REST Works Better

REST isn't outdated. It excels in specific scenarios.

Simple CRUD operations suit REST. When endpoints map directly to resources, REST is straightforward. GET /pets creates, reads, updates, deletes for pets.

Caching is critical - REST works well with HTTP caching. GET requests cache easily. GraphQL over POST is harder to cache.

Standard integrations - Third parties often prefer REST. It's universally understood. GraphQL adds learning curve for external developers.

File uploads - REST handles multipart requests naturally. GraphQL requires additional setup for file operations.

Public APIs - REST's predictable endpoints are easier to document and discover. GraphQL introspection helps but adds complexity.

When GraphQL Works Better

GraphQL shines when flexibility matters most.

Mobile applications benefit hugely. GraphQL reduces over-fetching on limited bandwidth. One request replaces many.

Complex data relationships work better. Fetch nested relationships in one query. No more N+1 request problems.

Rapid frontend development - Frontend teams can request exactly what they need. No backend changes for every UI tweak.

Multiple client types - Web, mobile, and TV apps need different data. GraphQL serves all from one API.

Analytics dashboards - Different widgets need different fields. Each component requests its own data shape.

Performance Considerations

GraphQL's flexibility can cause problems without careful design.

Complex queries - Clients might request enormous nested queries:

query {
  allPets {
    orders {
      items {
        product {
          manufacturer {
            warehouses {
              inventory
            }
          }
        }
      }
    }
  }
 }

Implement query complexity analysis to prevent this.

N+1 problems - A query fetching 100 pets, each with orders, might cause 101 database queries. Use DataLoader to batch database calls:

const DataLoader = require('dataloader');

const orderLoader = new DataLoader(async (petIds) => {
  const orders = await Orders.find({ petId: { $in: petIds } });
  return petIds.map(id => orders.filter(o => o.petId === id));
});

const resolvers = {
  Pet: {
    orders: (pet) => orderLoader.load(pet.id)
  }
};

Schema Design

GraphQL requires upfront schema design:

type Pet {
  id: ID!
  name: String!
  status: PetStatus!
  category: Category
  orders: [Order!]!
  createdAt: DateTime!
}

enum PetStatus {
  AVAILABLE
  PENDING
  SOLD
}

type Query {
  pet(id: ID!): Pet
  pets(status: PetStatus, limit: Int): [Pet!]!
}

type Mutation {
  createPet(input: CreatePetInput!): Pet!
  updatePet(id: ID!, input: UpdatePetInput!): Pet
  deletePet(id: ID!): Boolean!
}

This schema documents your API. Clients know exactly what's available.

Pet Store API: Both Options

The Pet Store API supports both REST and GraphQL. Use REST for straightforward CRUD operations. Use GraphQL when you need flexible queries.

REST endpoints:

GET /api/pets
POST /api/pets
GET /api/pets/:id
PUT /api/pets/:id
DELETE /api/pets/:id

GraphQL endpoint:

POST /api/graphql

The same data is available through both interfaces. Choose based on your specific needs.

Check docs.petstoreapi.com for complete GraphQL schema and examples.

Making Your Choice

Consider these questions:

  • Do clients need different data shapes? GraphQL
  • Is caching critical? REST
  • Is this a simple CRUD API? REST
  • Do you have nested data relationships? GraphQL
  • Are external developers consuming the API? REST
  • Is frontend velocity important? GraphQL

Many applications use both. REST for simple integrations, GraphQL for flexible queries. The Pet Store API gives you that flexibility.