Latticework

Command Palette

Search for a command to run...

GraphQL Fundamentals

Resolvers & Field Selection

22 min

Explanation

A REST endpoint like GET /users/1 returns a fixed shape decided by the server — every field, whether the client needs it or not. GraphQL flips this: the CLIENT sends a query describing exactly the shape it wants, and a resolver walks the underlying data, returning only those requested fields. This function is the resolver's core job, simplified to plain nested dicts instead of a real GraphQL schema.

def resolve(query, data):
    result = {}
    for field, subquery in query.items():
        if field not in data:
            continue
        if subquery is True:
            result[field] = data[field]
        elif isinstance(subquery, dict):
            if isinstance(data[field], list):
                result[field] = [resolve(subquery, item) for item in data[field]]
            else:
                result[field] = resolve(subquery, data[field])
    return result
Try it

Notice 'body' -- a potentially large field -- never gets fetched into the result at all, for either post, even though it exists in the underlying data. This is GraphQL's headline benefit: a mobile client that only needs titles and view counts never pays the cost of transferring full post bodies it won't display.

Loading editor…
Exercise

Write `resolve(query, data)`: `query` is a nested dict where each key maps to either `True` (return this scalar field as-is) or another dict (a nested selection to resolve recursively). If a field's value in `data` is a list, resolve the nested selection against EVERY item in that list. Return only the fields actually requested.

Quiz

REST APIs' resources-verbs module covered fixed-shape responses (a GET to /users/1 always returns the whole user object). What's the core idea GraphQL changes about that?

Checkpoint

You can implement field-selection resolution over nested data (including lists), the core mechanism that lets a GraphQL client request exactly the shape it needs.