GraphQL,Apollo:创建一个高效的模式



我最近开始研究GraphQL和Apollo的服务器开发。在下面的代码中,获取每个数据的公式在某种程度上是可以理解的。

schema.js

const { gql } = require('apollo-server');
const _ = require('lodash');
const onepieces = [
{
"id": "onepiece1",
"title": "원피스 1권",
"price": "1,360",
"desc": "동터오는 모험의 시대"
},
{
"id": "onepiece2",
"title": "원피스 2권",
"price": "1,360",
"desc": "대결 버기 해적단"
}
];
const narutos = [
{
"id": "naruto1",
"title": "나루토 1권",
"price": "1,360",
"desc": "나루토 모험의 시작"
},
{
"id": "naruto2",
"title": "나루토 2권",
"price": "1,360",
"desc": "나루토와 안개마을"
}
];
const typeDefs = gql`  
type Onepiece { id: ID, title: String, price: String, desc: String }
type Naruto { id: ID, title: String, price: String, desc: String }
type Query {
onepiece(id: String!): Onepiece,
naruto(id: String!): Naruto,
getOnepieces: [Onepiece],
getNarutos: [Naruto]
}
`;
const resolvers = {
Query: {
onepiece: (parent, args) => _.find(onepieces, {id: args.id}),
naruto: (parent, args) => _.find(narutos, {id: args.id}),
getOnepieces: () => onepieces,
getNarutos: () => narutos
}
};
module.exports = { typeDefs, resolvers };

但这是低效的代码。如果漫画书的类别增加,我应该继续添加查询。所以我想改进更方便和易读。

例如,我想管理漫画中的单件和火影忍者类别。

我该如何改进?

您可以从编写可能类别的GraphQL枚举开始。

enum Category { ONEPIECE NARUTO }

由于这两种漫画书具有相同的结构,因此可以使用单个GraphQL类型来表示它们。我们将把刚才写的类别合并在一起,这样你就可以知道哪一个是哪一个。

type ComicBook implements Node {
id: ID!
category: Category!
title: String!
price: String!
desc: String!
}

根据任意GraphQL对象的ID检索它们有一个标准的约定;虽然它来自Facebook的Relay Javascript客户端,但它并没有专门与该客户端绑定,我会在这里使用它。

interface Node {
id: ID!
}
type Query {
node(id: ID!): Node
}

这将取代您的顶级查询,以便按ID检索特定种类的书籍;你可以写一个类似的查询

{
node(id: "naruto1") {
... on ComicBook { category title price desc }
}
}

既然您有了类别枚举,您还可以编写一个顶级查询来返回可能按类别过滤的漫画书

type Query {
comicBooks(category: Category): [ComicBook!]!
}
{
comicBooks(category: ONEPIECE) { id title price desc }
}

有一些相应的代码更改可以使其工作;我可能会从将两个漫画书列表合并为一个列表开始,并在其中添加一个类似的类别字段。

完成此操作后,如果添加第三个类别,则需要将其添加到枚举并添加到数据集,但不需要对代码、GraphQL模式或查询进行任何其他更改。

最新更新