Khan / genqlient

a truly type-safe Go GraphQL client
MIT License
1.02k stars 99 forks source link

Painful to use with Dgraph #297

Open skandragon opened 8 months ago

skandragon commented 8 months ago

Is your feature request related to a problem? Please describe. Dgraph is kinda nice, in that it takes a schema and augments it with built-in resolvers that generally just work. However, using Dgraph with genqlient is painful.

The specific problems arise with not omitting empty values. While this is painful for ints, and mostly painful for strings, it is possible to work around this problem with schema types by insisting on pointers.

However, a filter is defined like this:

input ImageFilter {
  id: StringHashFilter
  name: StringExactFilter
  digest: StringExactFilter
  has: [ImageHasFilter]
  and: [ImageFilter]
  or: [ImageFilter]
  not: ImageFilter
}

input StringHashFilter {
  eq: String
  in: [String]
}

input StringExactFilter {
  eq: String
  in: [String]
  le: String
  lt: String
  ge: String
  gt: String
  between: StringRange
}

input StringRange {
  min: String!
  max: String!
}

enum ImageHasFilter {
  id
  name
  digest
  scans
  deployments
}

This query:

query queryImage($filter: ImageFilter!) {
    queryImage(filter: $filter) {
        id
        name
        digest
    }
}

produces a request like this:

{
  "query": "\nquery queryImage ($filter: ImageFilter!) {\n\tqueryImage(filter: $filter) {\n\t\tid\n\t\tname\n\t\tdigest\n\t}\n}\n",
  "variables": {
    "filter": {
      "name": {
        "eq": "moby/buildkit",
        "in": null,
        "le": "",
        "lt": "",
        "ge": "",
        "gt": ""
      },
      "digest": {
        "eq": "sha256:890dcae054e3039f6c6b76bf0da80a130fa6e6bb1f3624063ef0210ac2c57b06",
        "in": null,
        "le": "",
        "lt": "",
        "ge": "",
        "gt": ""
      },
      "has": null
    }
  },
  "operationName": "queryImage"
}

This will effectively break the query as it is asking for a silly request which is not self-consistent: asking for something that is eq to a string and also le, ge, lt, and gt the empty string makes no sense.

Describe the solution you'd like I really don't know what solution I'd like, other than to be able to (perhaps by-type) handle strings as pointers.

That, or a way to indicate what I'd like to have rendered somehow...

Describe alternatives you've considered

I can write my query to take the name and digest, but this creates a lot of "queryByNameAndDigest()" type almost-identical queries.

Additional context This is just one example of where rendering too much JSON gets me into trouble with Dgraph...

benjaminjkraft commented 5 months ago

Hmm, this seems similar to some of the issues that have come up with Hasura. Maybe take a look at #272 and (a) see if any of the existing config options or workarounds discussed there work for you and (b) comment on what overlaps or differs? Unfortunately I haven't had time to look back at the latest discussion there but I think there are some good ideas.