[英]How to split type definitions and resolvers into separate files in Apollo Server
index.ts:索引.ts:
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req, res }: any) => ({ req, res })
});
UserSchema.ts用户架构.ts
export const typeDefs = gql`
scalar TimeStamp
type Query {
getUser(id: Int!): User
}
type Mutation {
addUser(
name: String!
email: String
age: Int
register_at: TimeStamp!
): Boolean!
}
type User {
id: Int!
name: String!
email: String!
age: Int!
register_at: TimeStamp!
}
`;
UserResolver.ts UserResolver.ts
export const resolvers = {
TimeStamp: timeStamp,
Query: {
getUser: async (_: any, args: any) => {
const { id } = args;
return await User.findOne({ where: { id: id } });
}
},
Mutation: {
addUser: async (_: any, args: any) => {
const { name, email, age, register_at } = args;
try {
const user = User.create({
name,
email,
age,
register_at
});
await user.save();
return true;
} catch (error) {
return false;
}
}
}
};
I would like to know how I would initialize my Apollo Server instance if I had additional type definitions and resolvers, for example BookSchema.ts
and BookResolver.ts
.我想知道如果我有其他类型定义和解析器,例如
BookSchema.ts
和BookResolver.ts
,我将如何初始化我的 Apollo Server 实例。
The ApolloServer
constructor can accept an array instead of just the one DocumentNode
object. ApolloServer
构造函数可以接受一个数组,而不仅仅是一个DocumentNode
对象。 So you can do something like:因此,您可以执行以下操作:
const server = new ApolloServer({
typeDefs: [userTypeDefs, bookTypeDefs],
resolvers,
})
Note that if you want to split up an individual type's field definitions as well, you'll need to use type extension syntax.请注意,如果您还想拆分单个类型的字段定义,则需要使用类型扩展语法。 For example:
例如:
const typeDefsA = gql`
type Query {
users: [User!]!
}
`
const typeDefsB = gql`
extend type Query {
books: [Book!]!
}
`
const typeDefsC = gql`
extend type Query {
posts: [Post!]!
}
`
The above will be combined into a single Query
type.以上将组合成一个单一的
Query
类型。 You can have as many extensions as you want, but the type you're extending must exist (ie, you can't have just three extend type Query
definitions).您可以拥有任意数量的扩展,但是您要扩展的类型必须存在(即,您不能只有三个
extend type Query
定义)。 Keeping this in mind, I usually create a "base" set of type definitions like:牢记这一点,我通常会创建一组“基本”类型定义,例如:
type Query
type Mutation
Then all my other type definitions can extend these types.然后我所有的其他类型定义都可以扩展这些类型。 Notice that because these "base" types don't have any fields, we don't use curly brackets at all (an empty set of curly brackets will result in a syntax error!).
请注意,因为这些“基本”类型没有任何字段,所以我们根本不使用大括号(一组空的大括号将导致语法错误!)。
Your resolver map is a plain JavaScript object, so splitting it it up is trivial.您的解析器映射是一个普通的 JavaScript 对象,因此将其拆分是微不足道的。
const resolversA = {
Query: {
users: () => {...},
}
}
const resolversB = {
Query: {
books: () => {...},
}
}
However, if you attempt to combine these resolver maps using Object.assign
or spread syntax, you'll be hurting because any common properties (like Query
) will be overridden by each object.但是,如果您尝试使用
Object.assign
或 spread 语法组合这些解析器映射,您将受到伤害,因为任何公共属性(如Query
)都将被每个对象覆盖。 So do not do this:所以不要这样做:
const resolvers = {
...resolversA,
...resolversB,
}
Instead, you want to deep merge the objects, so that any child properties (and their properties, and so on) are merged as well.相反,您希望深度合并对象,以便也合并任何子属性(及其属性等)。 I recommend using
lodash
but there's any number of utilities you can use.我建议使用
lodash
但您可以使用任意数量的实用程序。
const resolvers = _.merge({}, resolversA, resolversB)
Your code might look something like this:您的代码可能如下所示:
userTypeDefs.ts用户类型定义文件
export default gql`
type User {
id: ID!
username: String!
books: [Book!]!
}
extend type Query {
users: [User!]!
}
`
bookTypeDefs.ts bookTypeDefs.ts
export default gql`
type Book {
id: ID!
title: String!
author: User!
}
extend type Query {
books: [Book!]!
}
`
userResolvers.ts userResolvers.ts
export default {
Query: {
users: () => {...},
},
User: {
books: () => {...},
},
}
bookResolvers.ts bookResolvers.ts
export default {
Query: {
books: () => {...},
},
Book: {
author: () => {...},
},
}
index.ts索引.ts
import userTypeDefs from '...'
import userResolvers from '...'
import bookTypeDefs from '...'
import bookResolvers from '...'
// Note: This is also a good place to put any types that are common to each "module"
const baseTypeDefs = gql`
type Query
`
const apollo = new ApolloServer({
typeDefs: [baseTypeDefs, userTypeDefs, bookTypeDefs],
resolvers: _.merge({}, userResolvers, bookResolvers)
})
I dont know, if it is good way of doing this, but you can do it like this.我不知道,如果这是这样做的好方法,但你可以这样做。
const typeDefA = `
name: String!
email: String!
phone: String!
`
const RootTypeDef = gql`
${typeDefA}
type Query {
users: [User]
}
`;
you can just take out user schema or any other schema and store it in normal variable, then add it like a variable in root schema.您可以取出用户架构或任何其他架构并将其存储在普通变量中,然后将其添加为根架构中的变量。
Please let me know, whether it is good practice or not.请让我知道,这是否是好的做法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.