-
Alex Kalderimis authored
GraphQL does not have inheritance, so it is an anti-pattern to use it to model polymorphism in our models. The correct approach is to model polymorphism as implementation of interfaces. Here there is a single `PackageType` interface, and then different implementations of that. Since the package types only differ in their metadata, we move the polymorphism down to the metadata fields, which an empty interface, implemented by metadata types. One thing that had to change was the `Query.package` field, which was previously `Query.package_composer_details`. This must change since the implementation of the lookup does not perform any type checking, and thus we cannot type the return value as a composer package. This would be an illegal and ill-typed down-cast. A good analogy for this is having a Java collection of ```java // yes, Cucumbers are fruits - look it up List<Fruit> bowl = List.of(new Apple(), new Banana(), new Cucumber()) ``` And then expecting to get an apple without a cast: ```java Apple fruit = bowl.get(0) // bad ``` This code would fail to compile in Java, and it is equally illegal in GraphQL, without the appropriate casting. We mark the composer metadata type as an orphan since it is only refered to as an implementation of the broader metadata type. We also split the type of packages into a top-level one, which is able to refer to versions, and a leaf node which may not. This prevents unbounded mutual cyclic recursion. Return successfully for all packages We can gradually add more specific package types, but it is important to always succeed with the data we can return.
671d5b51