How to split type definitions and resolvers into separate files in Apollo Server

女生的网名这么多〃 提交于 2020-05-24 05:14:27

问题


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

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.


回答1:


Type Definitions

The ApolloServer constructor can accept an array instead of just the one DocumentNode object. 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. You can have as many extensions as you want, but the type you're extending must exist (i.e., you can't have just three extend type Query definitions). 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!).

Resolvers

Your resolver map is a plain JavaScript object, so splitting it it up is trivial.

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

const resolvers = _.merge({}, resolversA, resolversB)

Putting it all together

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

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


来源:https://stackoverflow.com/questions/60747549/how-to-split-type-definitions-and-resolvers-into-separate-files-in-apollo-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!