Интерфейсы Graphql при использовании MongoDB

Я раздумываю над созданием GraphQL API с использованием MongoDB и пытаюсь разобраться в интерфейсах.

Я понял идею, стоящую за этим, и посмотрел кучу видео с докладами и практическими рекомендациями, но единственное, что я вижу, это то, как сделать распознаватель запросов.

Всегда отображается так: 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(),
    }
}

Идея состоит в том, что Family и Member — это отдельные документы, содержащие данные, а Group — это интерфейс для создания запроса, который их объединяет.


person jwknz    schedule 26.12.2020    source источник


Ответы (2)


редактировать: я перечитал ваш пост, и то, что вы пытаетесь получить здесь, может не существовать. Потому что в __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.

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

справочник по документации


Получите автоматически сгенерированные интерфейсы и типы.

Я нашел лучший способ автоматически получить типизацию для TS из вашей схемы, используя graphql- генератор кода. У него также есть плагин для получения автоматически сгенерированных моделей mongoDB.

Для быстрого ответа вставьте свою схему здесь.


Быстрая настройка машинописного текста:

  1. Установить

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

Он установит плагины cli и typescript + typescript-resolvers.

  1. В корне создайте codegen.yml и поместите:
overwrite: true
schema: 'http://localhost:3500/graphql'
generates:
  src/utils/codegen/graphql.ts:
    plugins:
      - 'typescript'
      - 'typescript-resolvers'
  1. выполнить команду:

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

  1. Теперь вы можете сделать следующее:
// 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 и автозаполнение

надлежащая проверка

person PawFV    schedule 26.12.2020

Для всех, кто приходит к этому вопросу - это код, который я должен был поместить внутрь 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)})
        } 

    })

},
person jwknz    schedule 29.12.2020