使用 MongoDB 时的 Graphql 接口

Posted

技术标签:

【中文标题】使用 MongoDB 时的 Graphql 接口【英文标题】:Graphql Interfaces when using MongoDB 【发布时间】:2021-04-03 19:10:13 【问题描述】:

我正在想办法使用 MongoDB 创建一个 GraphQL API,并且我正在尝试了解接口。

我明白了它背后的想法并观看了一堆关于谈话和操作方法的视频,但我看到的一件事是如何制作查询解析器。

总是这样显示:groups: () => ...

groups 将列在查询类型中,因此需要 mongodb 查询。

这是我需要找到答案的解析器:

... 里面有什么?

    Query: 
        groups: () =>  ... ,
        families: () => Family.find(),
        members: () => Member.find(),
    ,

我认为我在查询时遇到的问题是:“由于groups 不是 mongodb 文档,查询会是什么?”

更多信息:

这里是完整的 typedef

export const typeDefs = gql`

    interface Group 
        id: ID!
        name: String!
    

    type Family implements Group 
        id: ID!
        name: String! # persons family name
        numberOfPeople: Int
    

    type Member implements Group 
        id: ID!
        name: String! # persons first name
        age: Int!
    

    type Query 
        groups: [Group]
        families: [Family]
        members: [Member]
    


这是解析器

export const resolvers = 

    Group: 
        __resolveType(group, context, info)
          if(group.family)
            return 'Family';
          
    
          if(group.member)
            return 'Member';
          
    
          return null;
        ,
      ,

    Query: 
        groups: () =>  ... ,
        families: () => Family.find(),
        members: () => Member.find(),
    

这个想法是 FamilyMember 是保存数据的单独文档,Group 是创建组合它们的查询的接口。

【问题讨论】:

【参考方案1】:

编辑:我重新阅读了您的帖子,您在此处尝试访问的内容可能不存在。 因为在__resolveType,您正在针对架构属性进行验证。

// Group:
     
        __resolveType(group, context, info)
          if(group.family) // property family is not defined in a group implementation.
            return 'Family';
          
    
          if(group.member)
            return 'Member';
          
    
          return null;
        ,
      ,

您可能希望对来自实现的家庭或成员的定义的唯一属性执行验证,如下所示:

// Group:
     
        __resolveType(group, context, info)
          if(group.numberOfPeople)
            return 'Family';
          
    
          if(group.age)
            return 'Member';
          
    
          return null;
        ,
      ,

然后当你查询组时。

`

  groups 
    id
    name
    ... on Family 
      numberOfPeople 
    
    ... on Member 
      age
    
  

`

apollo docs reference


获取自动生成的接口和类型。

我找到了使用 graphql-code-generator 从您的架构中自动获取 TS 类型的最佳方法。它还有一个插件可以获取automatically generated mongoDB models

如需快速回复,请粘贴您的架构here。


快速设置打字稿:

    安装

npm i -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-resolvers

它将安装 cli 和 typescript + typescript-resolvers 插件。

    在您的根目录中创建 codegen.yml 并输入:
overwrite: true
schema: 'http://localhost:3500/graphql'
generates:
  src/utils/codegen/graphql.ts:
    plugins:
      - 'typescript'
      - 'typescript-resolvers'
    执行命令:

graphql-codegen --config codegen.yml --watch src/**/*.ts

    现在您可以执行以下操作:
// Import the types of your generated ts file.
import  MutationResolvers, QueryResolvers, Resolvers  from '@/utils/codegen/graphql'

const Query: QueryResolvers = 
  players: () => players


const Mutation: MutationResolvers = 
  updatePlayer: () => player


const resolvers: Resolvers = 
  Query,
  Mutation
;
export default resolvers;

截图示例:

intellisense and autocomplete

proper validation

【讨论】:

【参考方案2】:

对于任何提出这个问题的人 - 这是我必须放在 Query ... 中的代码

实际上是执行数据库查询的函数。

Groups 表示复数返回, Group 用于单数返回

groups: async () => 

    let types = mongoose.modelNames()

    let total = []

    for(let t of types) 
        let temp = await mongoose.model(t).find()
        total.push(temp)
    

    let flat = total.flat()

    return flat

,

group: (_,  id ) => 
    
    return mongoose.modelNames().map(async mn => 

        if (await mongoose.model(mn).exists("_id": ObjectID(id))) 
            return mongoose.model(mn).findOne("_id": ObjectID(id))
         

    )

,

【讨论】:

以上是关于使用 MongoDB 时的 Graphql 接口的主要内容,如果未能解决你的问题,请参考以下文章

如何在不创建 Mongoose 模型的情况下将 GraphQL 与 Mongoose 和 MongoDB 一起使用

规范化 MongoDB/Mongoose,以简化 GraphQL Schema?

GraphQL 如何使用 Nestjs 或 type-graphql 设置查询 MongoDB ref 集合

使用变量时的 GraphQL 错误请求

使用 mongoose 将带有 graphql 的文件上传到 mongodb

使用 Prisma + MongoDB + GraphQL 的嵌套关系返回 null