从 .gql 文件中命名导出多个 graphql 操作
Posted
技术标签:
【中文标题】从 .gql 文件中命名导出多个 graphql 操作【英文标题】:Named export multiple graphql operation from .gql files 【发布时间】: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 调用。
到目前为止,我尝试过的是这些工具/包:
graphql-tag/loader webpack-graphql-loader graphql-raw-loader据我所知,以上这些都不支持将每个文件导出为字符串的多个操作,仅支持作为 DocumentNode 的多个操作,或者将整个文件作为字符串。
graphql-codegen/typescript-graphql-files-modules 仅输出 DocumentNode 类型,没有将类型更改为字符串的选项如果还有其他问题,请告诉我。
【问题讨论】:
【参考方案1】:使用graphql-tools 中的documents-loading 和separateOperations 的解决方案 - 用于拆分 AST 的实用函数。步骤如下:
-
从
.gql
文件加载文档
将这个包罗万象的 AST 分成单独的 AST,这些 AST 代表可以单独发送到服务器的每个操作。
使用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
。其余步骤相同。
【讨论】:
以上是关于从 .gql 文件中命名导出多个 graphql 操作的主要内容,如果未能解决你的问题,请参考以下文章
如何在 apollo 的 graphql-gql 中使用从 npm 包导入的自定义 graphQL 类型
GraphQL 代码生成器 - 无法从 Nestjs 服务器端点加载我的 GQL 架构
为啥 WebStorm 在 Vue 组件或 .graphql 文件中的 apollo 对象内的 gql 查询中显示错误
在 Gatsby 中的 JSX 组件之外进行 graphql 查询