使用 Hasura graphql 模式时如何自定义 graphql-code-generator 生成的字段的类型

Posted

技术标签:

【中文标题】使用 Hasura graphql 模式时如何自定义 graphql-code-generator 生成的字段的类型【英文标题】:How to customize the type for a graphql-code-generator produced field when consuming a Hasura graphql schema 【发布时间】:2020-03-25 04:40:40 【问题描述】:

我想为 Hasura 生成的 graphql 模式中的特定字段覆盖 jsonb 类型,并通过 graphql-code-generator 运行。

我有一个 jsonb 类型的 customList 字段。 ths 用于包含一个 json 对象数组。当使用带有 TypeScript 插件的 graphql-code-generator 时,生成的类型解析为 any。我试图弄清楚如何仅使用该特定字段的自定义类型来覆盖它。

下面的 sn-ps 显示了 graphql 模式的相关部分,并覆盖了目标 graphql 类型。到目前为止,我尝试过的所有操作都会导致代码生成错误

GraphQl 架构

  //schema.json  
  ...
  
    "kind": "OBJECT",
    "name": “MyEntity”,
    "description": "columns and relationships of MyEntity",
    "fields": [
        ...
        
        "name": "customList",
        "description": "",
        "args": [
            
            "name": "path",
            "description": "JSON select path",
            "type": 
                "kind": "SCALAR",
                "name": "String",
                "ofType": null
            ,
            "defaultValue": null
            
        ],
        "type": 
            "kind": "SCALAR",
            "name": "jsonb",
            "ofType": null
        ,
        "isDeprecated": false,
        "deprecationReason": null
        ,
     
  

目标覆盖类型

//clientTypes.graphql

type ListItem 
  itemId: string!


extend type MyEntity 
  ccards: [ListItem!]

感谢您的帮助!

【问题讨论】:

【参考方案1】:

Typescript 插件有一个 scalars 配置选项,您可以在其中为任何标量定义自定义类型。

首先,您必须定义一个自定义客户端架构。扩展 MyEntity 类型以使用特殊的标量而不是 Jsonb

client-schema.graphql

scalar CardList

extend type MyEntity 
    ccards: CardList!

然后创建一个包含此标量类型的文件:

标量.ts

type ListItem 
  itemId: string!


export type CardList = ListItem[]

然后将新架构和自定义类型添加到graphql codegen的.yml配置中,如下所示:

schema:
  - https://your-remote-schema.url/v1/graphql:
documents: "src/**/*.ts"
generates:
  src/graphql/schema.ts:
    schema: src/graphql/client-schema.graphql
    plugins:
      - typescript
      - typescript-operations
    config:
      scalars:
        CardList: ./scalars#CardList

注意:路径应该是相对于生成文件的路径

https://github.com/dotansimha/graphql-code-generator/issues/153#issuecomment-776735610

【讨论】:

嗨,乔治,感谢您的详细回答。我尝试过,但由于Unable to merge GraphQL type "MyEntity": Field "customField" already defined with a different type. Declared as "MyCustomFieldType", but you tried to override with "jsonb" 之类的错误而失败(这里也提到了github.com/dotansimha/graphql-code-generator/issues/3051)。你是怎么解决的?是否有一个标志可以“忽略”该错误并强制它?感谢您的帮助。【参考方案2】:

您可以将 codegen 指向一个新文件 - 比如说 my-schema.js,然后按照您希望的方式操作架构。你可以使用任何你喜欢的工具(graphql-toolkit / graphql-compose / 直接 GraphQLSchema 操作)

【讨论】:

我的目标是维护远程模式的生成,但调整它转换为的类型。在这种情况下,将 JSONB 字段类型转换为 ListItem 类型(根据上面的示例) @arhnee 你找到解决方案了吗?

以上是关于使用 Hasura graphql 模式时如何自定义 graphql-code-generator 生成的字段的类型的主要内容,如果未能解决你的问题,请参考以下文章

为啥我使用 graphql > hasura > postgres 保存日期时出错

有没有办法使用 nodejs 重新加载 hasura 远程模式

如何从 iOS 中的 hasura graphql 查询中获取错误响应

Apollo 联合网关背后的 Hasura GraphQL 端点

如何对 Hasura 中的 ARRAY 字段类型运行 GraphQL 过滤器查询?

如何在 Apollo 客户端中传递地理查询变量(使用 React Native / Hasura GraphQL)