nerdsupremacist / GraphZahl

A Framework to implement Declarative, Type-Safe GraphQL Server APIs using Runtime Magic 🎩

Home Page:https://quintero.io/GraphZahl/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Better support for generics

nerdsupremacist opened this issue · comments

Currently Generics are not very easy to use...

The users usually have to define their own type names and more importantly. We end up creating one version per generic parameter used.

We should extract the non generic stuff and put it in an interface

Example of what I mean:

If I write

class Foo<Bar> {
    let bar: Bar
    let baz: String
    let item: Int
    
    func other() -> [Bar] { ... } 
}

And in our Schema we use: Foo<Bool> and Foo<Double?>

I want a schema that looks like this:

interface FooBase {
    baz: String!
    item: Int!
}

type FooOfBoolean implements FooBase {
    baz: String!
    item: Int!
    bar: Boolean!
    other: [Boolean!]!
}

type FooOfOptionalOfFloat implements FooBase {
    baz: String!
    item: Int!
    bar: Float
    other: [Float]!
}

This should also be compatible with our strategies for resolving subclassing:

So if we also have:

class SpecificFoo<T>: Foo<T> {
    let specific: T?
    let someData: Bool
}

then our final schema should be:

// Bases
interface FooBase {
    baz: String!
    item: Int!
}

interface SpecificFooBase {
    baz: String!
    item: Int!
    someData: Boolean!
}

// Interface Definitions of Foo superclass
interface FooOfBoolean {
    baz: String!
    item: Int!
    bar: Boolean!
    other: [Boolean!]!
}

interface FooOfOptionalOfFloat {
    baz: String!
    item: Int!
    bar: Float
    other: [Float]!
}

// Concrete Implementations of Foo super class
type __FooOfBoolean implements FooBase, FooOfBoolean {
    baz: String!
    item: Int!
    bar: Boolean!
    other: [Boolean!]!
}

type __FooOfOptionalOfFloat implements SpecificFooBase, FooBase, FooOfOptionalOfFloat {
    baz: String!
    item: Int!
    bar: Float
    other: [Float]!
}

// Concrete Implementations of Foo subclass
type SpecificFooOfBoolean implements SpecificFooBase, FooBase, FooOfBoolean {
    // Super Class
    baz: String!
    item: Int!
    bar: Boolean!
    other: [Boolean!]!

    // Subclass
    someData: Boolean!
    specific: Boolean
}

type SpecificFooOfOptionalOfFloat implements SpecificFooBase, FooBase, FooOfOptionalOfFloat {
    // Super Class
    baz: String!
    item: Int!
    bar: Float
    other: [Float]!
    
    // Subclass
    someData: Boolean!
    specific: Float
}

Or move to using this as soon as its possible: graphql/graphql-spec#190