How it works
The explanation, with examples you can run.
Resolvers
A resolver is a function (parent, args, context, info) => value | Promise<value>:
parent: the value the parent field resolved to (for root fields, a root value the server provides).args: the field's arguments, already coerced to their declared types.context: one object per request, shared by every resolver in it.info: the field's position in the query, its return type and the selection below it.
Most fields don't need a resolver. The default one returns parent[fieldName], so if Query.posts returns objects with a title property, Post.title just works. You write resolvers for root fields, for relationships (Post.author given authorId), and for computed values.
Watching it run
Press Run to see what your code prints, in order.
Runs in this browser, in an isolated frame with no access to this page. console.log, info, warn and error are shown; code runs as a classic script, so use an async function for await.
Post.author runs once per post, after Query.posts has produced the list and with each post as its parent. User.name then uses the default resolver. The list items are completed concurrently, which is why the lines for the two posts interleave. A real server such as graphql-js does the same walk, plus argument coercion, abstract type resolution, error handling and null checks.
Ordering
The spec lets a server resolve sibling fields of a query in any order, including in parallel; only top-level mutation fields must run serially. Children always wait for their parent's value. That makes the cost of a query depend on its shape: a list field multiplies the work of everything selected below it, and nothing in the execution model batches those calls for you. The next topic is about doing exactly that.
Check yourself
3 questions. Get them all right to finish this topic.
0 of 3 right so far. Get all three to finish this topic.