Определения типов
Конструктор ApolloServer
может принимать массив вместо одного DocumentNode
объекта. Таким образом, вы можете сделать что-то вроде:
const server = new ApolloServer({
typeDefs: [userTypeDefs, bookTypeDefs],
resolvers,
})
Обратите внимание, что если вы хотите разделить определения полей отдельного типа, вам нужно будет использовать синтаксис расширения типа. Например:
const typeDefsA = gql`
type Query {
users: [User!]!
}
`
const typeDefsB = gql`
extend type Query {
books: [Book!]!
}
`
const typeDefsC = gql`
extend type Query {
posts: [Post!]!
}
`
Вышеуказанное будет объединено в один тип Query
. У вас может быть столько расширений, сколько вы хотите, но тип, который вы расширяете , должен существовать (т. Е. У вас не может быть только трех extend type Query
определений). Имея это в виду, я обычно создаю «базовый» набор определений типов, например:
type Query
type Mutation
Тогда все мои другие определения типов могут расширять эти типы. Обратите внимание, что поскольку эти «базовые» типы не имеют полей, мы вообще не используем фигурные скобки (пустой набор фигурных скобок приведет к синтаксической ошибке!).
Resolvers
Ваша карта резольвера является простым JavaScript объектом, поэтому разбить его на части тривиально.
const resolversA = {
Query: {
users: () => {...},
}
}
const resolversB = {
Query: {
books: () => {...},
}
}
Однако, если вы попытаетесь объединить эти карты резольвера, используя Object.assign
или распространенный синтаксис, вы Будет больно, потому что любые общие свойства (например, Query
) будут переопределены каждым объектом. Так что не делает это:
const resolvers = {
...resolversA,
...resolversB,
}
Вместо этого вы хотите глубокое объединение объектов, чтобы любые дочерние свойства (и их свойства и т. Д.) ) также объединены. Я рекомендую использовать lodash
, но вы можете использовать любое количество утилит.
const resolvers = _.merge({}, resolversA, resolversB)
Соберите все вместе
Ваш код может выглядеть примерно так:
userTypeDefs .ts
export default gql`
type User {
id: ID!
username: String!
books: [Book!]!
}
extend type Query {
users: [User!]!
}
`
bookTypeDefs.ts
export default gql`
type Book {
id: ID!
title: String!
author: User!
}
extend type Query {
books: [Book!]!
}
`
userResolvers.ts
export default {
Query: {
users: () => {...},
},
User: {
books: () => {...},
},
}
bookResolvers.ts
export default {
Query: {
books: () => {...},
},
Book: {
author: () => {...},
},
}
index.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)
})