【问题标题】:How to customize the type for a graphql-code-generator produced field when consuming a Hasura graphql schema使用 Hasura graphql 模式时如何自定义 graphql-code-generator 生成的字段的类型
【发布时间】: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!]
}

感谢您的帮助!

【问题讨论】:

    标签: typescript graphql hasura graphql-codegen


    【解决方案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 你找到解决方案了吗?
    猜你喜欢
    • 2020-02-13
    • 2020-10-01
    • 2022-08-18
    • 2020-05-07
    • 2021-02-22
    • 2019-09-08
    • 2017-12-13
    • 2020-12-05
    • 2020-02-28
    相关资源
    最近更新 更多