You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从KeystoneJS的Apollo Server端点自动获取完整GraphQL Schema?

如何通过KeystoneJS GraphQL端点自动获取Schema

当然可以!你完全能通过KeystoneJS暴露的GraphQL端点自动获取Schema,不用修改任何Keystone内部代码——这和GraphQL Playground下载Schema用的是同一个机制:GraphQL内省查询。这是GraphQL的标准特性,所有符合规范的服务(包括Keystone默认的GraphQL端点)都支持。

实现步骤

核心思路是向Keystone的GraphQL端点发送一个标准的内省查询,拿到结构化的Schema数据后,再转换成可读的SDL(Schema Definition Language)格式,也就是你从Playground下载的那种文本格式。

1. 发送内省查询请求

内省查询是一个特殊的GraphQL查询,它会请求服务端返回自身的Schema元数据。你可以用任何HTTP客户端(比如fetch、axios)发送POST请求到Keystone的GraphQL端点,带上这个查询。

2. 转换结果为SDL格式

拿到内省查询的返回结果后,用graphql官方包的工具函数把结构化数据转换成SDL字符串,之后就能自动处理那些Apollo Server不识别的定义了。

完整代码示例(Node.js)

const { printSchema, buildClientSchema } = require('graphql');
const fetch = require('node-fetch');
const fs = require('fs');

async function fetchAndCleanKeystoneSchema(keystoneEndpoint) {
  // 标准的GraphQL内省查询,覆盖所有Schema细节
  const introspectionQuery = `
    query IntrospectionQuery {
      __schema {
        queryType { name }
        mutationType { name }
        subscriptionType { name }
        types {
          ...FullType
        }
        directives {
          name
          description
          locations
          args {
            ...InputValue
          }
        }
      }
    }

    fragment FullType on __Type {
      kind
      name
      description
      fields(includeDeprecated: true) {
        name
        description
        args {
          ...InputValue
        }
        type {
          ...TypeRef
        }
        isDeprecated
        deprecationReason
      }
      inputFields {
        ...InputValue
      }
      interfaces {
        ...TypeRef
      }
      enumValues(includeDeprecated: true) {
        name
        description
        isDeprecated
        deprecationReason
      }
      possibleTypes {
        ...TypeRef
      }
    }

    fragment InputValue on __InputValue {
      name
      description
      type { ...TypeRef }
      defaultValue
    }

    fragment TypeRef on __Type {
      kind
      name
      ofType {
        kind
        name
        ofType {
          kind
          name
          ofType {
            kind
            name
            ofType {
              kind
              name
              ofType {
                kind
                name
                ofType {
                  kind
                  name
                  ofType {
                    kind
                    name
                  }
                }
              }
            }
          }
        }
      }
    }
  `;

  try {
    // 发送请求到Keystone GraphQL端点
    const response = await fetch(keystoneEndpoint, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        // 如果你的Keystone服务需要认证,添加对应的授权头
        // 'Authorization': 'Bearer YOUR_AUTH_TOKEN'
      },
      body: JSON.stringify({ query: introspectionQuery })
    });

    const result = await response.json();
    if (result.errors) {
      throw new Error(`内省查询失败: ${JSON.stringify(result.errors)}`);
    }

    // 从内省数据构建Schema对象,再转换成SDL字符串
    const rawSchema = buildClientSchema(result.data.__schema);
    let sdl = printSchema(rawSchema);

    // 这里添加你的自定义清理逻辑,移除Apollo Server不识别的定义
    // 比如过滤Keystone生成的特定指令或类型
    // 示例:移除某个自定义指令
    // sdl = sdl.replace(/directive @someKeystoneDirective on .+/g, '');

    // 将清理后的SDL写入文件,供你的Apollo Server使用
    fs.writeFileSync('./cleaned-keystone-schema.graphql', sdl);
    console.log('Schema已成功获取并清理,保存到cleaned-keystone-schema.graphql');

    return sdl;
  } catch (error) {
    console.error('处理Schema时出错:', error);
    throw error;
  }
}

// 调用示例,替换成你的Keystone GraphQL端点
fetchAndCleanKeystoneSchema('http://your-keystone-instance.com/api/graphql');

关键注意事项

  • 认证处理:如果你的Keystone GraphQL端点启用了认证(比如JWT),记得在请求头中添加Authorization字段,带上有效的凭证,否则会返回权限错误。
  • 内省开关:大部分GraphQL服务默认开启内省查询,生产环境可能会禁用,但Keystone默认是开放的;如果遇到内省被禁用的情况,你需要在Keystone配置中开启它(不过你说不想修改Keystone内部,所以如果是默认配置就没问题)。
  • 清理逻辑:你可以根据自己的需求扩展代码中的清理步骤,比如用字符串替换、AST解析工具(如graphql-tools)来精准移除不需要的定义。

内容的提问来源于stack exchange,提问作者Cerulean

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 19:18:15