Именованный экспорт нескольких операций graphql из файлов .gql

#typescript #webpack #graphql #graphql-js #graphql-codegen

#typescript #webpack #graphql #graphql-js #graphql-codegen

Вопрос:

У меня есть некоторые операции (запрос / мутация, а иногда и некоторые фрагменты в нижней части файла), определенные в .gql файлах, иногда более одного в одном файле.

Я хотел бы импортировать их в свои файлы JS / TS, возможно, также сгенерировать соответствующие типы для TypeScript.

Я настроил здесь пример из 3 файлов:

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

queries.gql Файл является исходным кодом. Они должны генерировать соответствующие типы модулей в файле (см. generated-types.d.ts ), чтобы я мог импортировать их в свой index.ts файл и использовать его для выполнения вызовов graphql с помощью простого fetch .

То, что я пробовал до сих пор, — это следующие инструменты / пакеты:

Насколько я могу судить, ни одно из вышеперечисленных не поддерживает несколько операций для каждого файла, экспортируемого в виде строки, только несколько операций в виде DocumentNode или весь файл в виде строки.

Дайте мне знать, если возникнут еще какие-нибудь вопросы.

Ответ №1:

Решение с использованием документов-загрузка graphql-tools и separateOperations — служебная функция для разделения AST. Вот шаги:

  1. загрузка документов из .gql файлов
  2. Разделите этот всеобъемлющий AST на отдельные AST, которые представляют каждую операцию, которая может быть отправлена на сервер изолированно.
  3. Преобразование DocumentNode (AST) в строку с помощью функции печати graphql пакета.

Например.

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 . Остальные шаги те же.