调整Apollo团队(https://github.com/apollographql/GitHunt-API/tree/master/api)创建的GraphQL最佳实践示例,我很难想出一个能够生成人员>的解析器的解析器使用DataLoaders。
以下是api的示例(数据来自:https://github.com/steveluscher/zero-to-graphql/tree/master/zero-node)
给出 / people / 端点的输出,如:
{
"people": [
{
"username": "steveluscher",
"id": "1",
},
{
"username": "aholovaty",
"id": "2",
},
{
"username": "swillison",
"id": "3",
},
{
"username": "gvr",
"id": "4",
}
]
}
来自端点的人 / people / 1 /
{
"person": {
"last_name": "Luscher",
"username": "steveluscher",
"friends": [
"/people/2/",
"/people/3/"
],
"id": "1",
"email": "steveluscher@fb.com",
"first_name": "Steven"
}
我想要一个解析器,它会给我一个 Person 列表,如:
[
{
"person": {
"last_name": "Luscher",
"username": "steveluscher",
"friends": [
"/people/2/",
"/people/3/"
],
"id": "1",
"email": "steveluscher@fb.com",
"first_name": "Steven"
}
},
{
"person": {
"last_name": "Holovaty",
"username": "aholovaty",
"friends": [
"/people/1/",
"/people/4/"
],
"id": "2",
"email": "a.holovaty@django.com",
"first_name": "Adrian"
}
},
...
]
这是我到目前为止所得到的:
server.js
import { ApiConnector } from './api/connector';
import { People } from './api/models';
import schema from './schema';
export function run() {
const PORT = 3000;
const app = express();
app.use(bodyParser.json());
app.use('/graphql', graphqlExpress((req) => {
const query = req.query.query || req.body.query;
if (query && query.length > 2000) {
throw new Error('Query too large.');
}
const apiConnector = new ApiConnector();
return {
schema,
context: {
People: new People({ connector: apiConnector }),
},
};
}));
app.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql',
}));
const server = createServer(app);
server.listen(PORT, () => {
console.log(`API Server is now running on http://localhost:${PORT}`);
});
return server;
}
models.js
export class People {
constructor({ connector }) {
this.connector = connector;
}
getPeople() {
return this.connector.get(`/people/`);
}
getPerson(id) {
return this.connector.get(`/people/${id}/`);
}
}
connector.js
const API_ROOT = 'http://localhost:8080';
export class ApiConnector {
constructor() {
this.rp = rp;
this.loader = new DataLoader(this.fetch.bind(this));
}
fetch(urls) {
const options = {
json: true,
resolveWithFullResponse: true,
headers: {
'user-agent': 'Request-Promise',
},
};
return Promise.all(urls.map((url) => {
return new Promise((resolve) => {
this.rp({
uri: url,
...options,
}).then((response) => {
const body = response.body;
resolve(body);
}).catch((err) => {
console.error(err);
resolve(null);
});
});
}));
}
get(path) {
return this.loader.load(API_ROOT + path);
}
模式中的解析器会有类似的内容:
const rootResolvers = {
Query: {
people(root, args, context) {
return context.People.getPeople();
},
person(root, { id }, context) {
return context.People.getPerson(id)
}
},
};
到目前为止,我可以从/ people / id /获取第一个端点/ people /和一个人。但是如何改变它以获得一个人的名单?我不太确定这段代码应该在何处/何处。
非常感谢!
答案 0 :(得分:0)
您可以将人员解析器更改为类似下面的代码:
const rootResolvers = {
Query: {
people(root, args, context) {
const list = context.People.getPeople();
if (list && list.length > 0) {
return list.map(item => context.People.getPerson(item.id))
}
},
...
},
};
Ps:你说你正在使用dataLoader,所以我认为你的API调用只是被缓存,但如果不是这样,你需要实现一些缓存以避免多次调用相同的端点。