How to customize the type for a graphql-code-generator produced field when consuming a Hasura graphql schema
Asked Answered
F

3

6

I would like to override a the jsonb type for a speficic field in a graphql schema produced by Hasura and run through graphql-code-generator.

I have a customList field of type jsonb. Ths is used to contain an array of json objects. When using graphql-code-generator with the TypeScript plugin, the generated type resolves to any. I am trying to figure out how to override this with a custom Type for that specific field only.

The below snippets show the relevant section of graphql schema, and the targetted graphql type overrides. So far, everything I have tried results in codegen errors

GraphQl Schema

  //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
        },
     }
  }

Targetted Override Types

//clientTypes.graphql

type ListItem {
  itemId: string!
}

extend type MyEntity {
  ccards: [ListItem!]
}

Thanks for any help!

Flair answered 29/11, 2019 at 15:8 Comment(0)
P
1

There is a scalars config option for the Typescript plugin where you can define a custom type for any scalar.

First you have to define a custom client side schema. Extend the MyEntity type to have a special scalar instead of Jsonb

client-schema.graphql

scalar CardList

extend type MyEntity {
    ccards: CardList!
}

Then create a file that will contain type for this scalar:

scalars.ts

type ListItem {
  itemId: string!
}

export type CardList = ListItem[]

Then add the new schema and a custom type to the .yml config of the graphql codegen as follows:

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

Note: the path should be relative to the generated file

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

Pacifically answered 18/8, 2021 at 13:45 Comment(1)
Hi George, thanks for the detailed answer. I tried it but failed due to an error like this Unable to merge GraphQL type "MyEntity": Field "customField" already defined with a different type. Declared as "MyCustomFieldType", but you tried to override with "jsonb" (also mentioned here github.com/dotansimha/graphql-code-generator/issues/3051). How did you solve that? Is there a flag to "ignore" that error and force it? Thanks for your help.Szechwan
P
0

You can point the codegen to a new file - let's say my-schema.js, and then manipulate the schema the way you wish. You can use any tool you prefer for that (graphql-toolkit / graphql-compose / direct GraphQLSchema manipulation)

Phase answered 22/3, 2020 at 21:3 Comment(2)
my goal is to maintain the generation from the remote schema, but adjust the type it transforms to. In this case, transform a JSONB field type to a ListItem type (per example above)Flair
@Flair have you found any solution for that?Pe
R
0

To fix the problem "unable to merge type" that results from using @Georges workflow, add this line to the codegen.yml:

config:
  ignoreFieldConflicts: true

For complete reference, checkout this github issue.

Further reference

Rockwood answered 9/11, 2022 at 13:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.