GraphQL Fields and Nested Fields

Fields are the building blocks of every GraphQL query. Each field maps to a piece of data. When a field returns an object instead of a simple value, you can go deeper by selecting fields from that inner object too. This nesting is one of the most powerful features of GraphQL.

Scalar Fields vs Object Fields

A scalar field returns a simple value like a string, number, or boolean. An object field returns another type, which means you must go one level deeper to select individual values from it.

  type Address {
    street: String        ← Scalar field
    city:   String        ← Scalar field
    zip:    String        ← Scalar field
  }

  type Person {
    name:    String       ← Scalar field (stops here)
    age:     Int          ← Scalar field (stops here)
    address: Address      ← Object field (must go deeper)
  }

Querying Scalar Fields Only

  Query:                  Response:
  ──────                  ─────────
  {                       {
    person {                "data": {
      name                    "person": {
      age                       "name": "Maria",
    }                           "age": 32
  }                           }
                            }
                          }

Querying a Nested Object Field

When you ask for address, GraphQL knows that Address is a type, not a scalar. You must open another set of curly braces and specify which address fields you want.

  Query:                  Response:
  ──────                  ─────────
  {                       {
    person {                "person": {
      name                    "name": "Maria",
      address {               "address": {
        city                    "city": "Bengaluru",
        zip                     "zip": "560001"
      }                       }
    }                       }
  }                       }

Nesting Three Levels Deep

Real-world data often nests several levels deep. A company has departments, departments have employees, employees have contact details. GraphQL handles all of this in a single query.

  Types:
  ──────
  type Contact   { phone: String  email: String }
  type Employee  { name: String   contact: Contact }
  type Department{ name: String   employees: [Employee] }
  type Company   { name: String   departments: [Department] }

  Query:
  ──────
  {
    company {
      name
      departments {
        name
        employees {
          name
          contact {
            email
          }
        }
      }
    }
  }

  Response shape matches the query exactly:
  ───────────────────────────────────────────
  {
    "company": {
      "name": "Acme Corp",
      "departments": [
        {
          "name": "Engineering",
          "employees": [
            {
              "name": "Riya",
              "contact": { "email": "riya@acme.com" }
            }
          ]
        }
      ]
    }
  }

You Cannot Skip Levels

GraphQL requires you to be explicit at every level. If a field is an object type, you must open curly braces and name at least one field inside it. You cannot ask for the whole object without specifying fields.

  ✗ Invalid — address is an object type, fields required:
  ──────────────────────────────────────────────────────
  {
    person {
      name
      address       ← Error: must select subfields of Address
    }
  }

  ✓ Valid — fields specified at every level:
  ──────────────────────────────────────────
  {
    person {
      name
      address {
        city
      }
    }
  }

Why This Design Matters

Every field you list in the query triggers the matching resolver on the server. Fields you omit trigger no resolver and fetch no data. This means the network traffic and database load scale with exactly what the client actually needs — nothing more.

Leave a Comment