Our docs are a bit spare at the moment, but this means with code like:
type User struct {
Id int64
Name string
}
func rootUser(ctx context.Context, args struct { id int64 }) (*User, error) {
// ...
}
schemaRoot.FieldFunc("user", rootUser);
We can derive the graphql SDL types automatically (looking at the arguments and return values) and use them with other graphql tooling, but it saves folks time from writing out a separate schema and keeping it in sync.That being said, I don't agree with it. I'm not a fan of GraphQL for inter-service communication; it makes sense at the internet API boundary, but once you're inside your service mesh I prefer something simpler and easier to test, like gRPC.
The other option is to only write the Go types, then use codegen to generate the GraphQL schemas. In a way, I prefer this because it keeps everything in the same language, using all of the great tooling Go has.
There is some prior art for this; the Juniper [1] Rust library.
Then you either have a central team responsible for the public GraphQL API. They will typically write a server in Javascript that composes all the microservices. Or alternatively you have multiple product teams that all want separate GraphQL APIs tailored to their use case. They too typically use Javascript for the server.
When multiple languages are involved it turns out to be really useful to be able to use GraphQL SDL as the canonical representation and use code-gen on each stack. This is the use case GraphQL binding is intended for: https://github.com/graphql-binding/graphql-binding
The details get hard though, how do you represent unions vs enums? even knowing what implements an interface? default arguments? directives?
I'm thinking about adding something that generates a model if it doesn't exist, but after its generated it becomes the users problem to keep it in sync.
> recipe for mistakes and drift between the schemas and those types.
The type system enforces there is no drift, it won't compile if its not perfect.