web-dev-qa-db-fra.com

Comment étendez-vous des types dans GraphQL?

Par exemple, un Pet est un Animal avec un owner et name.

type Animal {
  species: String
}

type Pet extends Animal {
  owner: Owner
  name: String
}
9
atkayla

À partir de la version stable de juin 2018 de la spécification GraphQL , un type d'objet peut étendre un autre type d'objet:

Les extensions de type d'objet sont utilisées pour représenter un type qui a été étendu à partir d'un type d'origine. Par exemple, cela pourrait être utilisé pour représenter des données locales

Dans votre exemple,

type Animal {
  species: String
}

extend type Animal {
  owner: Owner
  name: String
}

Ce n'est pas un héritage en soi; vous pouvez uniquement étendre le type de base, pas créer de nouveaux types en fonction de celui-ci. Notez qu'il n'y a pas de nom pour le nouveau type; le type Animal existant est étendu.

La documentation graphql.org ne mentionne rien au sujet de extend, mais la documentation est certes terne et étant transitionée de Facebook propriété de la Fondation Linux. L'implémentation de référence JavaScript ne prend pas totalement en charge les extensions , mais puisque vous avez marqué votre question apollo-server , vous pouvez utiliser graphql-tools , ce qui fait :

const { graphql } = require('graphql');
const { makeExecutableSchema } = require('graphql-tools');

const typeDefs = `
  type Person {
    name: String!
  }
  extend type Person {
    salary: Int
  }  
  type Query {
    person: Person
  }
`;

const resolvers = {
  Query: {
    person: () => ({ name: "John Doe", salary: 1234 })
  }
}  

const schema = makeExecutableSchema({ typeDefs, resolvers });

graphql(schema, '{ person {name salary} }').then((response) => {
  console.log(response);
});

Pour l'héritage de type réel, voir bibliothèque graphql-s2s .

5
Dan Dascalescu

Ce n'est actuellement pas possible dans GraphQL, mais il existe un package expérimental qui pourrait être utile à cet effet.

https://github.com/Sydsvenskan/node-graphql-partials

Voir l'exemple:

partial LinkFields {
  links(
    rel: String
    type: String
  ): [Link]
}

partial DocumentFields using LinkFields {
  uuid: ID!

  # The document type, such as x-im/article
  type: String
  # If specified, then a list of the products to which this document's availability is limited
  products: [String]
  # The human readable name of the document, often used publicly to identify the document
  title: String

  # The specific path on the web page where this document is publicly available
  path: String

  # A single metadata block
  metaBlock(
    # The specific metadata block type to get
    type: String
  ): MetadataBlock
}

interface Document using DocumentFields {}

type AuthorDocument implements Document using DocumentFields {}

Ce qui se traduit par:

type AuthorDocument implements Document {
  links(
    rel: String
    type: String
  ): [Link]

  uuid: ID!

  # The document type, such as x-im/article
  type: String
  # If specified, then a list of the products to which this document's availability is limited
  products: [String]
  # The human readable name of the document, often used publicly to identify the document
  title: String

  # The specific path on the web page where this document is publicly available
  path: String

  # A single metadata block
  metaBlock(
    # The specific metadata block type to get
    type: String
  ): MetadataBlock
}

Ce que vous pouvez également faire, car ce ne sont que des chaînes, c'est de créer des fonctions d'assistance qui modifient la chaîne et insèrent les champs nécessaires.

Si vous êtes intéressé à suivre la discussion sur Github, vous pouvez jeter un œil au problème suivant.

https://github.com/graphql/graphql-js/issues/7

2
Ash Belmokadem