-
Notifications
You must be signed in to change notification settings - Fork 4
Description
I have a fairly large GraphQL API written in graphene
. I am interested in moving to ariadne
, but I'd rather not migrate the whole thing in one go. So, since both are based on graphql-core (more or less, the @2 vs @3 thing is a bit of a pain, but solvable), and both ultimately generate a graphql-core schema, I wondered, why not write some schema types in ariadne, while keeping the rest in graphene for now? This allows a step-by-step migration.
It turns out this is pretty easy from the Graphene side:
class External():
def __init__(self, type):
super(External, self).__init__()
self._type = type
class BetterGraphene(GrapheneGraphQLSchema):
def __init__(
self,
external_types=None,
**kwargs
):
self.external_types = external_types
GrapheneGraphQLSchema.__init__(self, **kwargs)
def type_map_reducer(self, map_, type_):
if isinstance(type_, External):
type_ = self.external_types[type_._type]
return super().type_map_reducer(map_, type_)
def get_field_type(self, map_, type_):
if isinstance(type_, External):
return self.external_types[type_._type]
return super().get_field_type(map_, type_)
Now I can do:
class Foo(graphene.ObjectType):
bar = Field(External("Bar"))
And I can create the Bar
type however I want, and pass it to the graphene Schema()
constructor. For example, I can create a schema with ariadne with make_executable_schema
, and take the Bar
type from the result.
This actually works!
The problem is that I can't link back. That is, if Bar
(no defined with Ariadne) wants to refer to a type that is still in Graphene. Or, simple custom scalars like a DateTime
- I can't have them defined in Graphene, and use them from an Ariadne type, and of course, they can't be defined twice.
Ordinarily I would say that I maybe I am just asking for too much: Making those two libraries interact. But as you can see by how little code is required on the Graphene side, this is actually pretty straightforward and without much complexity. Again, this is because the way graphql-core functions: It does the hard lifting, and we are just syntactic sugar on top.
And Graphene makes it super easy to change the mechanism of how the graphql-core schema is generated, by allowing a subclass to override methods.
In Ariadne, make_executable_schema
is a bit of a blackbox. What would be needed to make this work is just a little room in make_executable_schema
to allow to inject custom types; maybe allowing a custom resolve_type
function to be passed through to the ASTDefinitionBuilder
.
What are your thoughts?