简体   繁体   English

如何在 Apollo Server 中将类型定义和解析器拆分为单独的文件

[英]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.tsBookResolver.ts ,我将如何初始化我的 Apollo Server 实例。

Type Definitions类型定义

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!).请注意,因为这些“基本”类型没有任何字段,所以我们根本不使用大括号(一组空的大括号将导致语法错误!)。

Resolvers解析器

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)

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

相关问题 Graphql apollo 服务器解析器 arguments 类型 - Graphql apollo server resolvers arguments types 我们如何通过apollo-server模块在ApolloServer中传递数据源以及合并的graphql模式和解析器? - How can we pass datasource and merged graphql schema and resolvers in ApolloServer from apollo-server module? 错误:正文必须是字符串。 收到:{ resolvers: [[function HelloResolver]], validate: false } 使用 Type-graphql 和 apollo-server-express 时 - Error: Body must be a string. Received: { resolvers: [[function HelloResolver]], validate: false } when using Type-graphql and apollo-server-express 在JavaScript中导入/请求文件(而非模块)时如何使用类型定义? - How to use type definitions when importing/requiring files (not modules) in JavaScript? 如何使用VSCode在非打字稿文件中使用类型定义 - How to use type definitions in non typescript files using VSCode 如何在 Apollo Server 中正确键入上下文 object? - How can I correctly type the context object in Apollo Server? 如何连接 Apollo 客户端和 Apollo 服务器 - How to connect Apollo client with Apollo server 如何使用 Typescript 将 JSON 文件拆分为单独的文件 - How to split a JSON file into separate files using Typescript Apollo 解析器 - 等待另一个解析器的结果 - Apollo resolvers - await result from another resolver 如何在typescript + apollo中输入变异 - How to type a mutation in typescript + apollo
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM