到这里你已经会“写问询单”了,但还有一个关键问题:
总台怎么知道去哪里拿数据?
答案是 Resolver。
Resolver 可以理解成每个字段背后的“调度员函数”。
哪个字段被问到,就调用哪个调度员。
一个很常见的写法如下:
const resolvers = {
Query: {
resident: async (_parent, args, context) => {
return context.db.getResidentById(args.id);
},
tickets: async (_parent, args, context) => {
return context.db.listTickets({ status: args.status, first: args.first });
}
},
Resident: {
tickets: async (resident, args, context) => {
return context.db.getTicketsByResidentId(resident.id, args.status);
}
},
Ticket: {
resident: async (ticket, _args, context) => {
return context.db.getResidentById(ticket.residentId);
},
device: async (ticket, _args, context) => {
if (!ticket.deviceId) return null;
return context.db.getDeviceById(ticket.deviceId);
}
},
Mutation: {
createTicket: async (_parent, args, context) => {
return context.db.createTicket(args.input);
}
}
};Resolver 常见四个参数的心智:
parent:上一个层级已经查到的对象args:当前字段收到的参数context:整次请求共享的上下文,比如用户身份、数据库连接、loaderinfo:这次执行的元信息
执行路线图:
客户端 Query
↓
Schema 校验
↓
Query.resident resolver
↓
Resident.tickets resolver
↓
Ticket.device resolver
↓
组装成最终 JSON 响应把这一章吃透,你就真正理解了 GraphQL 的执行模型:
GraphQL 不是“自动查数据库”,而是“按字段逐层调度 Resolver”。