How do you extend types in GraphQL?

后端 未结 2 2035
悲哀的现实
悲哀的现实 2021-02-11 16:36

For example, a Pet is an Animal with an owner and name.

type Animal {
  species: String
}

type Pet extends A         


        
相关标签:
2条回答
  • 2021-02-11 17:09

    Starting with the June2018 stable version of the GraphQL spec, an Object type can extend another Object type:

    Object type extensions are used to represent a type which has been extended from some original type. For example, this might be used to represent local data

    In your example,

    type Animal {
      species: String
    }
    
    extend type Animal {
      owner: Owner
      name: String
    }
    

    This isn't inheritance per se; you can only extend the base type, not create new types based on it. Note there is no name for the new type; the existing Animal type is extended.

    The graphql.org documentation doesn't mention anything about extend, but the documentation is admittedly lackluster and being transitioned from Facebook's ownership to the Linux Foundation. The JavaScript reference implementation doesn't fully support extensions, but since you've tagged your question apollo-server, you can use graphql-tools, which does:

    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);
    });
    

    For actual type inheritance, see the graphql-s2s library.

    0 讨论(0)
  • 2021-02-11 17:19

    This is currently not possible in GraphQL, however there is an experimental package out there that might be useful for this purpose.

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

    See example:

    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 {}
    

    Which results in:

    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
    }
    

    What you can also do, since these are just strings is to create some helper functions that modify the string and insert the necessary fields.

    If you are intereseted in following the discussion on Github, you can have a look at the following issue.

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

    0 讨论(0)
提交回复
热议问题