1. The Over-Fetching & Under-Fetching Problem in REST

In traditional REST architecture, endpoints return fixed JSON shapes defined by the backend server. A mobile client calling `GET /api/v1/users/42` might receive 40+ user fields (address, billing, history) when it only needed the user's name and avatar URL. This wasted bandwidth is called over-fetching.

Bloated REST JSON Response Example (Over-Fetching)
{
  "id": 42,
  "first_name": "Alex",
  "last_name": "Rivers",
  "avatar_url": "https://cdn.example.com/avatar.jpg",
  "billing_address": { "street": "100 Main St", "zip": "90210" },
  "internal_flags": { "is_verified": true, "risk_score": 0.02 },
  "created_at": "2024-01-15T08:30:00Z"
}
Explanation: Fixed REST endpoints return every field regardless of what specific data the client requested.

2. Declarative Client-Driven JSON Shapes in GraphQL

GraphQL eliminates over-fetching by allowing clients to submit a declarative query specifying the exact fields needed. The GraphQL engine executes the query and returns a JSON response matching the exact structure requested.

GraphQL Declarative Query & Compact JSON Response
// 1. GraphQL POST Query Payload
// query { user(id: 42) { first_name avatar_url } }

// 2. Compact GraphQL JSON Response Payload
{
  "data": {
    "user": {
      "first_name": "Alex",
      "avatar_url": "https://cdn.example.com/avatar.jpg"
    }
  }
}
Explanation: The JSON response shape mirrors the query structure, reducing network bandwidth by up to 80%.

3. Error Handling Schemas — HTTP Status Codes vs errors Array

REST APIs communicate error state using native HTTP status codes (400 Bad Request, 404 Not Found, 422 Unprocessable Entity). Conversely, GraphQL endpoints always return HTTP 200 OK and serialize errors inside a top-level `"errors"` JSON array.

GraphQL Errors Array Structure
{
  "data": null,
  "errors": [
    {
      "message": "User not found for ID 42",
      "locations": [{ "line": 2, "column": 3 }],
      "path": ["user"]
    }
  ]
}
Explanation: GraphQL returns errors inside the JSON body while maintaining HTTP 200 status for the transport layer.