genqlient
genqlient copied to clipboard
Interfaces that implement other interfaces
Hello genqlient
team !
We are trying to generate queries from a GraphQL schema that contains interfaces that implements other interfaces.
According to the GraphQL specs, this should be valid (cf. issue #373 in the GQL repository).
Here is our (simplified) schema:
scalar DateTime
interface BaseEntity {
id: String!
createdAt: DateTime!
updatedAt: DateTime!
}
interface Transaction implements BaseEntity {
id: String!
createdAt: DateTime!
updatedAt: DateTime!
userId: String!
productId: String!
}
and the genclient.yaml
config:
schema: schema.graphql
operations:
- genqlient.graphql
generated: generated.go
package: main
bindings:
DateTime:
type: time.Time
When we the run the go run github.com/Khan/genqlient
command, we get the following error message:
schema.graphql:9: invalid schema file schema.graphql: Unexpected Name "implements"
Can you please confirm that genqlient
doesn't currently support this feature ?
Do you have some hints so we can help implement this in the codebase ?
Thank you very much for your hard work on this Go library !
Thanks for reporting! This is blocked by the GraphQL parser not supporting interfaces which implement interfaces (vektah/gqlparser#166). In theory genqlient should be more or less ready to support this once gqlparser does, although it's hard to be sure without being able to test it!
PRs to vektah/gqlparser#166 are very welcome in that repository btw! See some initial work here: https://github.com/vektah/gqlparser/pull/169
This is no longer blocked on gqlparser. I have some work in progress to support it on the genqlient side, but I ran into a few snags. I'll hopefully have more time to work on it soon!
@benjaminjkraft, did the snags go away? :)
The thing is that I would love to use genqlient for next project (which has just started) but since schema is full of "implements", I would have to use something else.
@benjaminjkraft similar situation to stiray. starting a new project and would like to use this, but the schema I'm referencing is full of implements. any updates?
edit. got this working, view my comment below
I also have full of implements when trying to use linear graphql API @benchristel 🙏
Actually, I just ran go get -u github.com/Khan/genqlient
instead of go get github.com/Khan/genqlient
, and I think it updated gqlparser to the working version, because I don't get that error anymore.
Unfortunately the snags won't go away on their own! But I may have some time in the next few weeks to take another look.
Or, yes, you can try simply using the latest gqlparser; if you need to do anything significant with interfaces implementing other interfaces (e.g. embed one fragment in another) it may not work quite right but it will at least let you use the rest of the schema!
@benjaminjkraft
I got a different error output with the same scenario of interfaces implementing other interfaces
schema.graphql:14: interface ContactInfo had non-object implementation ElectronicContact
The problem is reproducible in v0.6 & v0.7
Here a simplified version of our case
genqlient.yaml
schema: schema.graphql
operations: get-customer-details.graphql
generated: generated.go
schema.graphql :
schema {
query: Query
}
type Query {
customer(id: String!): Customer
}
type Customer {
id: String!
contactInfo: ContactInfo!
}
interface ContactInfo {
active: Boolean!
}
interface ElectronicContact implements ContactInfo{
active: Boolean!
}
type ElectronicContactEmail implements ElectronicContact & ContactInfo {
active: Boolean!
personalEmail: String
workEmail: String
}
type ElectronicContactTwitter implements ElectronicContact & ContactInfo {
active: Boolean!
personalUsername: String
workUsername: String
}
type Phone implements ContactInfo {
active: Boolean!
phoneNumber: String
countryCode: String
}
type Mail implements ContactInfo {
active: Boolean!
name: String
addressLine1: String
addressLine2: String
zipCode: String
country: String
}
get-customer-details.graphql
query GetAllCustomerDetails {
customer(id: "someCustomerId") {
id
contactInfo {
... on ElectronicContactEmail {
personalEmail
workEmail
}
... on ElectronicContactTwitter {
personalUsername
workUsername
}
... on Phone {
phoneNumber
countryCode
}
... on Mail {
name
addressLine1
addressLine2
zipCode
country
}
}
}
}