GraphQL 模式拼接选择集中是不是禁止使用列表类型的字段?

Posted

技术标签:

【中文标题】GraphQL 模式拼接选择集中是不是禁止使用列表类型的字段?【英文标题】:Are fields with list types forbidden in GraphQL schema stitching selection sets?GraphQL 模式拼接选择集中是否禁止使用列表类型的字段? 【发布时间】:2021-06-12 20:52:47 【问题描述】:

我有一个如下所示的实体数组:

const aEntities = [
    
        id: 1,
        name: 'Test',
        oneToManyRelation: [
            
                id: 2
            ,
            
                id: 3
            
        ],
        oneToOneRelation: 
            id: 1
        
    
];

实体由AType 类型表示。我想在单独的子模式中扩展这种类型,并证明可以添加分别从oneToOneRelationoneToManyRelation 的内容派生其值的字段。

以下架构,实现基于oneToOneRelation 的派生字段,工作正常:

const aSchema = makeExecutableSchema(
    resolvers: 
        Query: 
            aEntities: () => aEntities
        
    ,
    schemaTransforms: [stitchingDirectivesValidator],
    typeDefs: gql`
        $allStitchingDirectivesTypeDefs

        type AType 
            id: ID!
            name: String!
            oneToOneRelation: AEmbeddedType!
        

        type AEmbeddedType 
            id: ID!
        

        type Query 
            aEntities: [AType!]!
        
    `
);

const bSchema = makeExecutableSchema(
    resolvers: 
        AType: 
            oneToOneId: ( oneToOneRelation ) => oneToOneRelation.id
        ,
        Query: 
            aEntities_fromBSchema: (_,  keys ) => keys,
        
    ,
    schemaTransforms: [stitchingDirectivesValidator],
    typeDefs: gql`
        $allStitchingDirectivesTypeDefs

        type AType @key(selectionSet: " oneToOneRelation  id  ") 
            oneToOneId: String!
        

        scalar Key

        type Query 
            aEntities_fromBSchema(keys: [Key!]!): [AType!]! @merge
        
    `
)

const schema = stitchSchemas(
    subschemaConfigTransforms: [stitchingDirectivesTransformer],
    subschemas: [
        
            schema: aSchema
        ,
        
            schema: bSchema,
        
    ]
)

但是一旦我将oneToManyRelation id 添加到 selectionSet 中,我就会遇到问题:

const aSchema = makeExecutableSchema(
    resolvers: 
        Query: 
            aEntities: () => aEntities
        
    ,
    schemaTransforms: [stitchingDirectivesValidator],
    typeDefs: gql`
        $allStitchingDirectivesTypeDefs

        type AType 
            id: ID!
            name: String!
            oneToManyRelation: [AEmbeddedType!]!
            oneToOneRelation: AEmbeddedType!
        

        type AEmbeddedType 
            id: ID!
        

        type Query 
            aEntities: [AType!]!
        
    `
);

const bSchema = makeExecutableSchema(
    resolvers: 
        AType: 
            oneToManyIds: ( oneToManyRelation ) => oneToManyRelation.map(( id ) => id),
            oneToOneId: ( oneToOneRelation ) => oneToOneRelation.id
        ,
        Query: 
            aEntities_fromBSchema: (_,  keys ) => keys,
        
    ,
    schemaTransforms: [stitchingDirectivesValidator],
    typeDefs: gql`
        $allStitchingDirectivesTypeDefs

        type AType @key(selectionSet: " oneToOneRelation  id , oneToManyRelation  id  ") 
            oneToOneId: String!
            oneToManyIds: [String!]!
        

        scalar Key

        type Query 
            aEntities_fromBSchema(keys: [Key!]!): [AType!]! @merge
        
    `
)

我收到以下错误:

oneToManyRelation.map is not a function

当我在 aEntities_fromBSchema 解析器中记录 keys 参数时,似乎 oneToManyRelation 根本没有被解析为一个数组,而是一个(空)对象:

[
  
    oneToOneRelation: [Object: null prototype]  id: '1' ,
    oneToManyRelation: [Object: null prototype]  id: undefined ,
    __typename: 'AType'
  
]

graphql-tools v 7.0.2 开始,是否禁止在键选择集中引用列表类型?看起来我实际上可以通过使用在 SDL 之外定义的子模式合并配置来规避这个问题(没有批处理,而是使用 argsselectionSet 配置参数),但是出于验证/网关的原因,我更愿意拥有我所有的子模式都包含它们所有的类型合并指令作为 SDL 指令。

铌。这是对现实世界问题的简化表示。

Nb2。在现实世界的应用程序中,我的一个子模式是我无法控制的远程 GraphQL 应用程序,因此需要在拼接层中进行一些高级定制。

编辑:只需将以下内容添加到子模式配置的合并选项中似乎可以解决问题。有人知道为什么这似乎不能用 SDL 指令重现吗? (或者这样做的好方法?)

// AType

  argsFromKeys: (keys) => ( keys ),
  fieldName: 'aEntities_fromBSchema',
  key: ( oneToOneRelation, oneToManyRelation ) => ( oneToManyRelation, oneToOneRelation ),
  selectionSet: ' oneToOneRelation  id , oneToManyRelation  id  '

【问题讨论】:

【参考方案1】:

您可能发现了一个错误!请在 GitHub 存储库上打开一个问题,以便我们跟踪它。 :)

【讨论】:

以上是关于GraphQL 模式拼接选择集中是不是禁止使用列表类型的字段?的主要内容,如果未能解决你的问题,请参考以下文章

使用身份验证的 graphql 模式拼接

模式拼接两个远程 Prisma/GraphQL 模式

hasura graphql 模式拼接demo

GraphQL 拼接 VS 合并模式

使用最新版本的 Apollo 和 GraphQL 工具进行远程模式拼接

处理子查询中的 graphql 模式拼接错误