简体   繁体   English

Graphql 使用 MongoDB 时的接口

[英]Graphql Interfaces when using MongoDB

I am figuring my way around creating a GraphQL API using MongoDB and I am trying to get my head around interfaces.我正在考虑使用 MongoDB 创建 GraphQL API 的方法,并且我正在尝试了解接口。

I get the idea behind it and watched a bunch of videos on talks and howto's, but the one thing I am seeing is how to make the query resolver.我明白了它背后的想法,并观看了一堆关于会谈和操作方法的视频,但我看到的一件事是如何制作查询解析器。

It is always displayed like this: groups: () => {... }它总是这样显示: groups: () => {... }

groups would be listed in the query type, so it would need the mongodb query. groups将列在查询类型中,因此需要 mongodb 查询。

This is the resolver that I need to find the answer for:这是我需要找到答案的解析器:

What goes inside of the {...} ? {...}里面有什么?

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

I think the area I am stuck in when it comes to the query is that: "What would the query be since groups is not a mongodb document?"我认为我在查询时遇到的问题是:“查询是什么,因为groups不是 mongodb 文档?”

MORE INFORMATION:更多信息:

Here is the full typedef这是完整的 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]
    }
}

Here is the resolver这是解析器

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

The idea is that Family and Member are separate documents which hold the data and that Group is the interface to create a query that combines them.这个想法是FamilyMember是保存数据的单独文档,而Group是创建组合它们的查询的接口。

edit: I re-readed your post and what you are trying to access here may not exist.编辑:我重新阅读了您的帖子,您在这里尝试访问的内容可能不存在。 Because at the __resolveType you are validating against a schema property.因为在__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;
        },
      },

You may want to perform a validation against a defined unique property from an implementation either Family or Member like follows:您可能希望针对来自实现 Family 或 Member 的定义的唯一属性执行验证,如下所示:

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

Then when you query groups.然后当您查询组时。

`
{
  groups {
    id
    name
    ... on Family {
      numberOfPeople 
    }
    ... on Member {
      age
    }
  }
}
`

apollo docs reference 阿波罗文档参考


Get Automatically generated interfaces and typings.获取自动生成的界面和类型。

I have found the best way to get typings for TS automatically from your schema using graphql-code-generator .我找到了使用graphql-code-generator从您的架构中自动获取 TS 类型的最佳方法。 It has also a plugin to get automatically generated mongoDB models它还有一个插件可以自动生成 mongoDB 模型

For a quick response paste your schema here .如需快速响应,请在此处粘贴您的架构。


Quick setup for typescript: typescript 的快速设置:

  1. Install安装

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

It will install cli and typescript + typescript-resolvers plugins.它将安装 cli 和 typescript + typescript-resolvers 插件。

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

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

  1. Now you can do something as follows:现在您可以执行以下操作:
// 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;

Screenshot examples:截图示例:

intellisense and autocomplete智能感知和自动完成

proper validation适当的验证

For anyone who comes to this question - this is the code I had to put inside of the Query{... }对于遇到这个问题的任何人 - 这是我必须放在Query{... }中的代码

Effectively it is the function that executes the database query.实际上,执行数据库查询的是 function。

Groups is for a plural return, Group is for a singular return 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)})
        } 

    })

},

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM