【问题标题】:Named export multiple graphql operation from .gql files从 .gql 文件中命名导出多个 graphql 操作
【发布时间】:2021-01-11 00:15:46
【问题描述】:

我在.gql 文件中定义了一些操作(查询/变异,有时还有文件底部的一些片段),有时在一个文件中定义了多个。

我想将这些导入到我的 JS/TS 文件中,可能还会为 TypeScript 生成相应的类型。

我在这里设置了一个 3 个文件的例子:

https://gist.github.com/balazsorban44/352d5295f604fb4274bfc934937737a1

queries.gql 文件是源文件。它们应该在文件中生成相应的模块类型(参见generated-types.d.ts),因此我可以将它们导入我的index.ts 文件并使用它通过简单的fetch 进行graphql 调用。

到目前为止,我尝试过的是这些工具/包:

据我所知,以上这些都不支持将每个文件导出为字符串的多个操作,仅支持作为 DocumentNode 的多个操作,或者将整个文件作为字符串。

如果还有其他问题,请告诉我。

【问题讨论】:

    标签: typescript webpack graphql graphql-js graphql-codegen


    【解决方案1】:

    使用graphql-tools 中的documents-loadingseparateOperations 的解决方案 - 用于拆分 AST 的实用函数。步骤如下:

    1. .gql文件加载文档
    2. 将这个包罗万象的 AST 分成单独的 AST,这些 AST 代表可以单独发送到服务器的每个操作。
    3. 使用graphql 包的print 函数将DocumentNode(AST) 转换为字符串。

    例如

    queries.gql:

    query Something {
      name
      id
    }
    
    query SomethingElse($email: String!) {
      somethingelse(email: $email) {
        phone
        ...SomeFragment
      }
    }
    
    fragment SomeFragment on User {
      email
      address
    }
    

    index.ts:

    import { loadDocumentsSync } from '@graphql-tools/load';
    import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
    import path from 'path';
    import { separateOperations, print, buildSchema } from 'graphql';
    import express from 'express';
    import { graphqlHTTP } from 'express-graphql';
    import fetch from 'node-fetch';
    
    const documents = loadDocumentsSync(path.resolve(__dirname, './queries.gql'), {
      loaders: [new GraphQLFileLoader()],
    });
    const { Something, SomethingElse } = separateOperations(documents[0].document!);
    
    console.log(print(Something));
    console.log(print(SomethingElse));
    
    // server
    const schema = buildSchema(`
      type User {
        id: ID!
        name: String
        email: String
        address: String
        phone: String
      }
      type Query {
        somethingelse(email: String!): User
        Something: User
      }
    `);
    const root = {
      somethingelse({ email }) {
        return { id: 1, name: 'teresa teng', email, address: 'Japan', phone: '123' };
      },
    };
    const app = express();
    app.use(
      '/graphql',
      graphqlHTTP({
        schema: schema,
        rootValue: root,
        graphiql: true,
      }),
    );
    app.listen(4000, () => console.log('graphql server running on localhost 4000'));
    
    // test
    fetch('http://localhost:4000/graphql', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ query: print(SomethingElse), variables: { email: 'teresa.teng@gmail.com' } }),
    })
      .then((res) => res.json())
      .then((res) => console.log(res))
      .catch(console.error);
    

    执行结果:

    query Something {
      name
      id
    }
    
    query SomethingElse($email: String!) {
      somethingelse(email: $email) {
        phone
        ...SomeFragment
      }
    }
    
    fragment SomeFragment on User {
      email
      address
    }
    
    graphql server running on localhost 4000
    { data:
       { somethingelse:
          { phone: '123',
            email: 'teresa.teng@gmail.com',
            address: 'Japan' } } }
    
    

    顺便说一句,如果您提供的工具/包可以从.gql 文件加载文档,您可以使用它而不是使用graphql-tools。其余步骤相同。

    【讨论】:

      猜你喜欢
      • 2021-05-23
      • 2020-10-13
      • 1970-01-01
      • 1970-01-01
      • 2018-03-05
      • 2019-09-03
      • 2018-10-28
      • 2021-11-23
      • 1970-01-01
      相关资源
      最近更新 更多