This PR partially addresses #8. Currently, most graphql servers (and particularly for our case, neo4j over apollo) don't appropriately support interfaces inheriting from interfaces. Thus, if we have smth like
then CloudResourceEntity will be a regular interface without implementing the secondary interface in the schema that will be emitted. As we autogenerate types, we want any field or directive (e.g., a @relationship directive) that is of type ResourceEntity, to support CloudResourceEntity. We want to be able to do this in a best effort way for auto-generated code, until things are supported by neo4j or other servers.
For types that implement CloudResourceEntity, they need to declare that they implement ResourceEntity as well, so for python, we just need to fix inheritance for CloudResourceEntity classes, as well as any types that implement the interface (e.g., so as to not have method resolution order problems). Thus, assuming a type
@dataclass(kw_only=True)
class ResourceEntity(DataClassJSONMixin):
...
@dataclass(kw_only=True)
class CloudResourceEntity(ResourceEntity):
...
@dataclass(kw_only=True)
class AWSCloudPlatform(CloudPlatform, CloudResourceEntity):
...
This was not supported as of today as
interfaces were not being taken into account wrt to inheritance, and thus never had a parent class
we did not resolve multi-inheritance properly for types, thus class AWSCloudPlatform parent class hierarchy would be getting emitted as (CloudPlatform, CloudResourceEntity, ResourceEntity), which messes up MRO.
This still leaves a question open as to how do we deal with accessing said types via graphql when it comes to neo4j. For instance, if we have a field of type ResourceEntity, and we want to pass CloudResourceEntity there, that is allowed by the RFC (see https://github.com/graphql/graphql-spec/pull/373) but this won't be understood by the graphql server for now. Unions of interfaces are also not allowed by the SPEC (https://github.com/graphql/graphql-js/issues/451).
That said, I don't know if we will ever run into this issue, since we would be able to pass all types implementing the interface as inputs (they will be implementing all interfaces in case of intermediate interfaces by default, thus AWSCloudPlatformalways has to implement both CloudResourceEntityandResourceEntity). Thus I think this will be OK for now for most practical scenarios.
Since the GraphQL that will be getting emitted by Apollo+Neo4j as of today will strip away the implements part of any interface, essentially converting
we are forced to pass interface inheritance information via the config file. To do so, we use interfaceInheritance as a magic key in the yaml config, so we would be passing smth like:
This PR partially addresses #8. Currently, most graphql servers (and particularly for our case, neo4j over apollo) don't appropriately support interfaces inheriting from interfaces. Thus, if we have smth like
then
CloudResourceEntity
will be a regular interface without implementing the secondary interface in the schema that will be emitted. As we autogenerate types, we want any field or directive (e.g., a@relationship
directive) that is of typeResourceEntity
, to supportCloudResourceEntity
. We want to be able to do this in a best effort way for auto-generated code, until things are supported by neo4j or other servers.For
types
that implementCloudResourceEntity
, they need to declare that they implementResourceEntity
as well, so for python, we just need to fix inheritance forCloudResourceEntity
classes, as well as any types that implement the interface (e.g., so as to not have method resolution order problems). Thus, assuming a typewe want the emitted python code to be
This was not supported as of today as
AWSCloudPlatform
parent class hierarchy would be getting emitted as(CloudPlatform, CloudResourceEntity, ResourceEntity)
, which messes up MRO.This still leaves a question open as to how do we deal with accessing said types via graphql when it comes to neo4j. For instance, if we have a field of type
ResourceEntity
, and we want to passCloudResourceEntity
there, that is allowed by the RFC (see https://github.com/graphql/graphql-spec/pull/373) but this won't be understood by the graphql server for now. Unions of interfaces are also not allowed by the SPEC (https://github.com/graphql/graphql-js/issues/451).That said, I don't know if we will ever run into this issue, since we would be able to pass all types implementing the interface as inputs (they will be implementing all interfaces in case of intermediate interfaces by default, thus
AWSCloudPlatform
always has to implement bothCloudResourceEntity
andResourceEntity
). Thus I think this will be OK for now for most practical scenarios.Since the
GraphQL
that will be getting emitted by Apollo+Neo4j as of today will strip away theimplements
part of any interface, essentially convertingto
we are forced to pass interface inheritance information via the config file. To do so, we use
interfaceInheritance
as a magic key in the yaml config, so we would be passing smth like: