Как разделить определения типов и распознаватели на отдельные файлы в Apollo Server - PullRequest
0 голосов
/ 19 марта 2020

index.ts:

  const server = new ApolloServer({
    typeDefs,
    resolvers,
    context: ({ req, res }: any) => ({ req, res })
  });

UserSchema.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

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;
      }
    }
  }
};

Я хотел бы знать, как инициализировать мой Экземпляр сервера Apollo, если у меня были дополнительные определения типов и распознаватели, например BookSchema.ts и BookResolver.ts.

1 Ответ

0 голосов
/ 19 марта 2020

Определения типов

Конструктор 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)
})
...