我有一个客户端-服务器设置,其中客户端(create-react-app)在 localhost:3000 上运行,服务器是一个构建在节点上的快速服务器,我正在尝试构建 graphql 模式解析器设置。
我可以在服务器上导入 .graphql 文件,但是,在客户端,我通过graphql-tools使用此设置。
当我尝试在前端构建架构解析器时,我正在导入
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { addResolversToSchema } from '@graphql-tools/schema';
import { loadSchema } from '@graphql-tools/load';
Run Code Online (Sandbox Code Playgroud)
...这会导致此错误:
./node_modules/@graphql-tools/graphql-file-loader/index.mjs 无法从非 EcmaScript 模块导入命名导出“AggregateError”(仅提供默认导出)
经过研究,我发现这是与webpack相关的问题。
这个问题有解决办法吗?
我们已经实现了模式拼接,其中GraphQL服务器从两个远程服务器获取模式并将它们拼接在一起.当我们只使用Query和Mutations时,一切都运行正常,但现在我们有一个用例,我们甚至需要缝合订阅,远程模式已经通过它实现了auth.
我们很难搞清楚如何通过网关将connectionParams中收到的授权令牌从客户端传递到远程服务器.
这就是我们如何反省架构:
API网关代码:
const getLink = async(): Promise<ApolloLink> => {
const http = new HttpLink({uri: process.env.GRAPHQL_ENDPOINT, fetch:fetch})
const link = setContext((request, previousContext) => {
if (previousContext
&& previousContext.graphqlContext
&& previousContext.graphqlContext.request
&& previousContext.graphqlContext.request.headers
&& previousContext.graphqlContext.request.headers.authorization) {
const authorization = previousContext.graphqlContext.request.headers.authorization;
return {
headers: {
authorization
}
}
}
else {
return {};
}
}).concat(http);
const wsLink: any = new WebSocketLink(new SubscriptionClient(process.env.REMOTE_GRAPHQL_WS_ENDPOINT, {
reconnect: true,
// There is no way to update connectionParams dynamically without resetting connection
// connectionParams: () => …
Run Code Online (Sandbox Code Playgroud) apollo graphql apollo-server graphql-subscriptions graphql-tools
我认为我只是错误地使用了这个模块,这就是我收到错误的原因。根据文档,我可以将解析器和模式数组传递给mergeSchemas
来自 的函数graphql-tools
。但我收到此错误:
Error: Apollo Server requires either an existing schema, modules or typeDefs
这是代码:
应用程序.js
import { ApolloServer } from 'apollo-server'
import schema from './modules'
const server = new ApolloServer({
schema
})
server.listen().then(({ url }) => {
console.log(` Server ready at ${url}`)
})
Run Code Online (Sandbox Code Playgroud)
合并模式
import { mergeSchemas } from 'graphql-tools'
import bookSchema from './book/schema/book.gql'
import bookResolver from './book/resolvers/book'
export const schema = mergeSchemas({
schemas: [bookSchema],
resolvers: [bookResolver] // ==> Maybe I have to merge these before …
Run Code Online (Sandbox Code Playgroud) 我想graphql-tools/addMockFunctionsToSchema
按照以下模式在模拟解析器中模拟错误响应:
const mocks = {
...,
Mutation: () => ({
getToken: (_, { password }) => {
if (password === 'password') {
return { value: casual.uuid }
} else {
throw new Error('Incorrect email or password')
}
}
})
}
const schema = makeExecutableSchema({`
type Token { value: ID! }
type Mutation {
getToken(email: String!, password: String!): Token
}
`});
addMockFunctionsToSchema({ schema, mocks});
Run Code Online (Sandbox Code Playgroud)
这可以正常工作,并且确实返回GraphQL错误,但是:
所以我有这两个模式
Schema1
type Permission {
relation: Relation
}
enum Relation {
ONE
TWO
THREE
}
Run Code Online (Sandbox Code Playgroud)
SCHEMA2
type Permission {
relation: Relation
}
enum Relation {
FOUR
FIVE
SIX
}
Run Code Online (Sandbox Code Playgroud)
预期结果类似于:(但我对不同的想法持开放态度)合并后我想做的查询是:
{
permissions{
relation
}
}
Run Code Online (Sandbox Code Playgroud)
得到一个结果
"permissions": [
{
"relation": "ONE"
},
{
"relation": "SIX"
}
]
Run Code Online (Sandbox Code Playgroud)
要么
"permissions": [
{
"relation": "schema1ONE"
},
{
"relation": "schema2SIX"
}
]
Run Code Online (Sandbox Code Playgroud)
和突变像:
mutation{
createPermission(
relation: ONE
){
relation
}
}
mutation{
createPermission(
relation: SIX
){
relation
}
}
Run Code Online (Sandbox Code Playgroud)
要么
mutation{
createPermission(
relation: …
Run Code Online (Sandbox Code Playgroud) 我想知道是否有办法在 GraphQL 中共享 Input 和 Type 之间的公共字段,这样我就不必在多个地方定义相同的字段集。
例子:
input PersonInput {
id: String!
name: String
address: String
}
type Person {
id: String!
name: String
address: String
}
Run Code Online (Sandbox Code Playgroud)
我知道 Fragment 可能是一个解决方案,但如果我的理解是正确的,使用 Fragment 总是需要您设置一个 ON 条件,使其看起来像这样:
Fragment PersonCommonFields on Person {
...
}
Run Code Online (Sandbox Code Playgroud)
似乎没有办法指定“on Person/PersonInput”。
import { IResolvers } from "graphql-tools";
我试图从 graphql-tools 导入 IResolvers 并收到消息 Module: '"../node_modules/graphql-tools"' has no returned member 'IResolvers'。
我的依赖项是:“apollo-server-express”:“^ 3.1.2”,“graphql”:“^ 15.5.1”,“graphql-tools”:“^ 8.1.0”
这是因为我使用的是 apollo 3 而不是具有 IResolver 的 apollo 2 吗?
我有一个由 apollo-server 提供支持的 node.js 项目。我使用自定义@admin
指令对查询、突变和对象字段进行权限检查。对于查询和变异,此指令会引发错误,对于字段,它返回 null 而不是实际值。
现在,我想将 graphiql ui 添加到我的项目中,以便其他开发人员可以探索我的 graphql 模式。但是,我希望他们以匿名用户的方式查看模式,即他们不应该知道@admin
字段和@admin
查询的存在以及所有更改(即使是非管理员更改)。即使那些拥有执行这些操作的凭据(即以管理员身份登录)的人也不应该看到架构的这些部分。
据我了解,graphiql发送特殊内省查询,其中包含__schema
和__type
区域显示模式和它的文档。
是否有可能以某种方式修改我的架构,该架构是使用makeExecutableSchema
from构建的graphql-tools
以实现我的目标?
我正在使用graphql-tool模拟数据进行测试。
我希望在选择用户时进行模拟,它会打开一个详细信息页面并显示用户公司信息。
询问
const query = `
query User($id: ID!) {
user(id: $id) {
id
company
}
}
`;
Run Code Online (Sandbox Code Playgroud)
模拟服务器
import { addMockFunctionsToSchema } from 'graphql-tools';
import casual from 'casual';
const allUserIds = ['u1', 'u2', 'u3'];
const mocks = {
User: () => ({
id: casual.random_element(allUserIds),
name: casual.name,
company: casual.company_name
})
};
addMockFunctionsToSchema({ schema, mocks });
Run Code Online (Sandbox Code Playgroud)
但是,现在,当我使用参数id进行查询时'u1'
,它将返回例如一个随机用户ID 'u2'
,这给我在前端显示它带来了一些麻烦。
我以为我可以在下面做类似的事情,但事实证明我错了。user
是undefined
在下面的代码。
const mocks = {
User: (user) => ({
id: user.id || casual.random_element(allUserIds), …
Run Code Online (Sandbox Code Playgroud) 我的困境始于将我的 graphql 模式从单个 .graphql 文件扩展到多个文件的简单愿望,这样我就可以更好地组织模式,这样它就不会变成一个失控的大文件。
我的原始布局非常简单,我在schema.graphql
文件中有一个工作模式。我将能够使用importSchema('server/schema.graphql')
graphql-import 库将其解析为字符串,该库现已弃用https://github.com/ardatan/graphql-import
他们提到它已合并到graphql-tools
最新版本中,并在此处提供迁移教程https://www.graphql-tools.com/docs/migration-from-import该教程似乎非常简单,因为他们的第一个示例几乎说明了正是我的代码的样子(除了我不使用 es6 导入但旧的 fashoined 需要):
import { importSchema } from 'graphql-import';
import { makeExecutableSchema } from 'graphql-tools';
const typeDefs = importSchema(join(__dirname, 'schema.graphql'));
const resolvers = {
Query: {...}
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
Run Code Online (Sandbox Code Playgroud)
然后他们说要修改它,只需进行这些更改
import { loadSchemaSync } from '@graphql-tools/load';
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader';
import { addResolversToSchema } from '@graphql-tools/schema';
const schema = loadSchemaSync(join(__dirname, 'schema.graphql'), { loaders: [new GraphQLFileLoader()] …
Run Code Online (Sandbox Code Playgroud) graphql-tools ×10
graphql ×9
apollo ×4
graphql-js ×2
node.js ×2
typescript ×2
express ×1
javascript ×1
reactjs ×1