When a field returns an object type, the executor resolves its sub-fields using the returned value as parentValue:
Nested Resolution
// Query type with a user field that returns a User object"user": PrismGraphQLField( name: "user", type: .object("User"), args: [PrismGraphQLArgument(name: "id", type: .nonNull(.id))], resolver: { info in let id = info.arguments["id"] as? String ?? "" // Return a dictionary — this becomes parentValue for User fields return ["id": id, "name": "Alice", "email": "alice@example.com"] })// User type fields resolve from parentValuelet userType = PrismGraphQLObjectType( name: "User", fields: [ "id": PrismGraphQLField(name: "id", type: .nonNull(.id), args: [], resolver: { info in (info.parentValue as? [String: Any])?["id"] }), "name": PrismGraphQLField(name: "name", type: .string, args: [], resolver: { info in (info.parentValue as? [String: Any])?["name"] }), "posts": PrismGraphQLField( name: "posts", type: .list(.object("Post")), args: [], resolver: { info in let userId = (info.parentValue as? [String: Any])?["id"] as? String ?? "" // Fetch posts for this user let db = info.context as? PrismDatabase let rows = try await db?.query( "SELECT * FROM posts WHERE author_id = ?", parameters: [.text(userId)] ) ?? [] return rows.map { ["id": $0["id"], "title": $0["title"]] } } ) ])