gabotechs / graphqxl

GraphQXL is a new language built on top of the GraphQL syntax that extends the original language with some additional features useful for creating scalable and big server side schemas. This repository contains the source code for the GraphQXL compiler.
https://gabotechs.github.io/graphqxl
MIT License
272 stars 8 forks source link

Implicit inheritance #47

Closed Benthem closed 1 year ago

Benthem commented 1 year ago

It would seem like a nice step towards DRY if inheritance did not require the spread operator for the exact interface that is implemented.

interface Person {
    parent: String!
    childs: [String!]!
}

type Dad implements Person {
    job_title: String!
}

type Kid implements Person {
    school_name: String!
}

Would compile to

interface Person {
    parent: String!
    childs: [String!]!
}

type Dad implements Person {
    parent: String!
    childs: [String!]!
    job_title: String!
}

type Kid implements Person {
    parent: String!
    childs: [String!]!
    school_name: String!
}
gabotechs commented 1 year ago

There is a couple of reason for not doing it like this:

type Resource implements Common { id: String! }

implicit interfaces would disable this possibility, as it would always be auto-implemented with a nullable `String`.
By forcing the caller to implement it themselves this is possible:

<table>
    <thead>
        <tr>
            <th>
                Source GraphQXL
            </th>
            <th>
                Compiled GraphQL
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td> 

```graphql
interface Common {
    id: String
}

type Resource implements Common {
    ...Required<Common>
}
                              #GraphQXL

interface Common {
    id: String
}

type Resource implements Common {
    id: String!
}
                               #GraphQL

With an implicit interface implementation, users are bound to have the implemented fields at the beginning.

Source GraphQXL Compiled GraphQL
```graphql interface Common { id: String } type Resource implements Common { thisMustComeFirst: Int thisMustBeTheLast: Int } #GraphQXL ``` ```graphql interface Common { id: String } type Resource implements Common { id: String thisMustComeFirst: Int thisMustBeTheLast: Int } #GraphQL ```

But if the implementer uses the spread operator, it is able to choose the position of the implemented fields:

Source GraphQXL Compiled GraphQL
```graphql interface Common { id: String } type Resource implements Common { thisMustComeFirst: Int ...Common thisMustBeTheLast: Int } #GraphQXL ``` ```graphql interface Common { id: String } type Resource implements Common { thisMustComeFirst: Int id: String thisMustBeTheLast: Int } #GraphQL ```

Honestly, I doubt that this last reason would bother anyone, but who knows 🤷🏼‍♂️

I have not done a deep research of why the original GraphQL language is not already supporting this, but they may have a reason maybe? here they say something https://github.com/graphql/graphql-spec/issues/335 about it .

Benthem commented 1 year ago

Thanks for the great response 😊 Looking forward to using graphqxl in a project