从.gql文件命名为导出多个graphql操作

问题描述

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

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

在这里设置了3个文件示例:

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

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

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

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

让我知道是否还有其他问题。

解决方法

使用documents-loading中的graphql-toolsseparateOperations的解决方案-用于拆分AST的实用程序功能。步骤如下:

  1. .gql个文件中加载文档
  2. 将此功能全面的AST分离为代表可以单独发送到服务器的每个操作的AST。
  3. 使用DocumentNode包的print函数将graphql(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。其余步骤相同。