You define a schema with types (type User { name: String, posts: [Post] }) and a resolver function per field that knows how to fetch it. The engine walks the query, calling resolvers to assemble exactly the requested shape. The schema is the contract; resolvers are the implementation that can pull from databases, other APIs, anywhere.