来自角度对象的Graphql输入对象

Posted

技术标签:

【中文标题】来自角度对象的Graphql输入对象【英文标题】:Graphql input object from angular object 【发布时间】:2019-10-31 15:21:02 【问题描述】:

我想使用一个角度对象作为 graphql 突变的输入变量。我已经研究了几个小时,并且似乎尝试了每个示例的所有可能组合,包括使用这样的变量,这会引发变量不匹配的错误。

return this.apollo.mutate(
        mutation: gql`
          mutation saveLicense(license:License) 
            saveLicense(license:$license) 
              licenseId,
              name,
              body,
              deprecated,
              fsfLibre,
              osiApproved,
              spdxId,
              orLaterLicense,
              familyName,
              familyNameRegex,
              cleanName,
              twoNameRegex,
              nameAttributeList 
                attribute,
                index
              ,
              attributes 
                attributeType,
                key
              
            
          
        `,
         variables license:license
     );

最终,提交给服务器的查询需要看起来像这样(当然有值):

return this.apollo.mutate(
        mutation: gql`
          mutation 
            saveLicense(
               license:
                   licenseId:"",
                                  name:"",
                                  licenseFamily:"",
                                  version:"",
                                  replacementLicenseId:"",
                                  spdxId:"",
                                  deprecated: false,
                                  fsfLibre:false,
                                  osiApproved:false,
                                  orLaterLicense:false,
                                  familyName:"",
                                  familyNameRegex:"",
                                  cleanName:"",
                                  twoNameRegex:"",
                                  body:"",
                                  description:""
                
              )
              licenseId,
              name,
              body,
              deprecated,
              fsfLibre,
              osiApproved,
              spdxId,
              orLaterLicense,
              familyName,
              familyNameRegex,
              cleanName,
              twoNameRegex,
              nameAttributeList 
                attribute,
                index
              ,
              attributes 
                attributeType,
                key
              
            
          
        `,
     );

上述查询有效,但我无法弄清楚如何将 angular 对象转换为查询所需的 graphql 字符串形式。经过数小时的研究,我唯一的解决方案是将对象转换为 json 表示,然后再返回并将许可证作为字符串传递。这显然是一个严重的黑客攻击!

JSON.parse(JSON.stringify(mylicense))

我正在寻找如何将变量与 angular/Apollo 一起使用的示例,或者寻找一种将 angular 对象转换为可以在 Graphql 中使用的字符串的更简洁的方法。

【问题讨论】:

【参考方案1】:

不要使用字符串插值将变量注入查询 - 将变量定义为操作定义的一部分,然后使用它们代替输入文字。

首先,我们通过提供名称和类型来定义变量。注意变量总是以$开头:

mutation saveLicense($license: LicenseInput) 

然后将变量用作参数的输入,如下所示:

saveLicense(license: $license) 

最后将适当的 javascript 对象作为变量传递给mutate 函数:

const variables = 
  license: 
    licenseId: 123,
    // and so on
  

this.apollo.mutate( mutation, variables )

【讨论】:

你好丹尼尔。请查看我更新的顶部突变,它正确反映了我尝试使用变量的方式。这给了我以下错误:错误:GraphQL错误:NonInputTypeOnVariable类型的验证错误:变量GraphQL错误的类型错误:VariableTypeMismatch类型的验证错误:变量类型'License'与预期类型'LicenseInput'@'saveLicense'不匹配 @John 所以你的变量类型应该是LicenseInput 而不是License。您需要查阅服务的架构以确定 LicenseInput 采用哪些字段。如果其中一个字段不匹配,您将收到一个错误。 有趣。我正在为我的服务器 graphql 实现使用leagen/graphql-spqr,服务器类型是许可证。我想,在幕后,它会根据我请求的许可证类型自动创建一个 LicenseInput。 成功了!我刚刚在 Angular 中创建了我的 License 类的副本并将其命名为 LicenseInput,然后在我的 graphql 中使用了 LicenseInput 类型,它就可以工作了!我想我应该更好地注意错误在说什么。感谢您的帮助。我总是想念一些简单的东西。 @John 我不熟悉那个库。如果服务器公开了 GraphiQL 接口,我建议使用它来构建您的查询。 GraphiQL 提供基于架构的语法高亮显示。【参考方案2】:

这里是documentation如何在graphql中使用变量。

你应该改变你的代码如下。

return this.apollo.mutate(
  mutation: gql`
    mutation saveLicense($license: License) 
      saveLicense( license: $license ) 
        licenseId,
        name,
        body,
        deprecated,
        fsfLibre,
        osiApproved,
        spdxId,
        orLaterLicense,
        familyName,
        familyNameRegex,
        cleanName,
        twoNameRegex,
        nameAttributeList 
          attribute,
          index
        ,
        attributes 
          attributeType,
          key
        
      
    
  `,
    variables license: license
);

【讨论】:

以上是关于来自角度对象的Graphql输入对象的主要内容,如果未能解决你的问题,请参考以下文章

使用输入对象的graphql突变

对象数组的Graphql输入类型[重复]

对象作为突变中的输入变量:GraphQL - Apollo - React

GraphQL SPQR 扩展输入对象的变异参数

Graphql 不接受带引号的键

Gatsby 中单个 JSON 对象的 GraphQL 查询