【问题标题】:Dynamic GraphQL schema?动态 GraphQL 架构?
【发布时间】:2018-12-17 11:07:19
【问题描述】:

我有一个要提交表单数据的突变,此数据可能因您填写的表单而异。

表单会很多,它们将共享相同的“步骤”(每个表单由 1 个或多个页面/步骤组成)。

所以,我们可能有这些可重复使用的步骤:

  • 最喜欢的水果
  • 出生日期
  • 姓名和姓氏

还有这两种形式:

  • 通用信息 (genericInfo):姓名 + 出生日期
  • 你吃什么? (whatYouEat): 姓名+最爱水果

我需要一种方法来进行单一突变,允许定义表单名称,并采用需要基于此类表单名称进行验证的 data 对象。

例如,如果我称之为突变:

submitForm(formName: $formName, formData: $formData) {
  resultMessage
}

formName 设置为genericInfoformData 设置为{ nameAndSurname: 'Foo Bar', favFruit: 'apple' },它应该会抛出一个错误,因为genericInfo 不期望favFruit,而是dateOfBirth

这可以用 GraphQL 实现吗?有没有更好的方法可以到达这里?

【问题讨论】:

    标签: graphql apollo


    【解决方案1】:

    GraphQL 不直接允许这样做。输入对象类型具有固定结构,并且没有条件验证(内置;您的解析器函数可能会根据其自身的检查产生错误,这些检查比架构中的内容更丰富)。

    我见过的最常见的模式采用Relay GraphQL mutation conventions(即使您不希望您的客户使用 Relay)。每个可能的操作都有一个突变(在您的情况下,每个提交的表单有一个突变)和每个突变的不同输入对象类型。

    还要注意输入对象类型可以嵌套,所以在你的例子中,你可以写

    input Name {
      givenName: String!
      surname: String!
    }
    
    input Fruit {
      name: String!
    }
    
    input WhatYouEatInput {
      name: Name!
      fruit: Fruit!
    }
    
    mutation {
      whatYouEat(input: WhatYouEatInput!): WhatYouEatPayload!
    }
    

    这将允许跨不同突变类型重用架构的公共部分。

    【讨论】:

    • 谢谢,这是我正在使用的当前实现...但是如果我要拥有 100 个表单,它就无法扩展:-(
    【解决方案2】:

    如果 GraphQL 提供了一个可以用作输入的 Union 类型,就可以做到这一点。这是has been suggested before,但近期似乎没有实施的计划。

    因此,由于您将在表单数据上拥有数十种可能的组合,我认为您最好的选择是只发送一个 JSON 格式的字符串与数据,然后自己进行验证,使用一些定义所有可能的结构formName 及其允许的字段。

    但是这样你就不会利用 GraphQL 打字系统。

    【讨论】:

    • 即使我们使用 JSON 类型进行存储。过滤数据太难了。
    猜你喜欢
    • 2019-04-05
    • 2017-05-11
    • 2018-12-21
    • 2020-11-26
    • 2017-06-12
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多