首页 文章

如何在另一个查询字段中包装远程模式?

提问于
浏览
2

Apollo graphql-tools 现在有Schema Stitching,这很棒 . 我想合并多个 endpoints 以生成类似于GraphQL Hub的模式,如下所示:

query { github: { ... } # GitHub Schema twitter: { ... } # Twitter Schema myOwnGraphqlSchema: { ... } }

如何做到这一点的最佳方法是什么?

GitHub问题:https://github.com/apollographql/graphql-tools/issues/439

叉在这里进行测试:https://launchpad.graphql.com/3xlrn31pv

谢谢 .

1 回答

  • 6

    编辑:我相信现在可以使用新的graphql-tools 3.0了! https://dev-blog.apollodata.com/the-next-generation-of-schema-stitching-2716b3b259c0


    Original answer:

    这是一个解决方案(黑客?)我提出了,但可能有更好的方法来做到这一点:

    • 使用 introspectSchemamakeRemoteExecutableSchema 获取远程模式

    • 使用 printSchema 获取架构类型defs

    • 将printSchema收到的根typedef QueryMutation 重命名为其他内容,例如 GitHubQueryGitHubMutation

    • 使用类型为 GitHubQuerygithub 字段创建根查询typedef

    • 创建 github 解析程序,该解析程序使用 execute 方法在远程github模式中运行 GitHubQuery

    Source code: https://launchpad.graphql.com/3xlrn31pv

    import 'apollo-link'
    import fetch from 'node-fetch'
    import {
      introspectSchema,
      makeExecutableSchema,
      makeRemoteExecutableSchema,
    } from 'graphql-tools'
    import { HttpLink } from 'apollo-link-http'
    import { execute, printSchema } from 'graphql'
    
    const link = new HttpLink({ uri: 'http://api.githunt.com/graphql', fetch })
    
    async function getGithubRemoteSchema() {
      return makeRemoteExecutableSchema({
        schema: await introspectSchema(link),
        link,
      })
    }
    
    async function makeSchema() {
      const githubSchema = await getGithubRemoteSchema()
      const githubTypeDefs = printSchema(githubSchema)
    
      const typeDefs = `
            ${githubTypeDefs // ugly hack #1
          .replace('type Query', 'type GitHubQuery')
          .replace('type Mutation', 'type GitHubMutation')}
    
        type Query {
          github: GitHubQuery
        }
    
        type Mutation {
          github: GitHubMutation
        }
        `
    
      return makeExecutableSchema({
        typeDefs,
        resolvers: {
          Query: {
            async github(parent, args, context, info) {
              // TODO: FIX THIS
    
              // ugly hack #2
              // remove github root field from query
              const operation = {
                ...info.operation,
                selectionSet:
                  info.operation.selectionSet.selections[0].selectionSet,
              }
              const doc = { kind: 'Document', definitions: [operation] }
    
              const result = await execute(
                githubSchema,
                doc,
                info.rootValue,
                context,
                info.variableValues,
                info.operation.name
              )
    
              return (result || {}).data
            },
          },
        },
      })
    }
    
    export const schema = makeSchema()
    

相关问题