Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend field types when in reference #39

Closed
iamshabell opened this issue Mar 8, 2023 · 5 comments
Closed

Extend field types when in reference #39

iamshabell opened this issue Mar 8, 2023 · 5 comments

Comments

@iamshabell
Copy link

iamshabell commented Mar 8, 2023

Example:

export const userType = g.type('User', {
    id: g.string(),
    email: g.string(),
    name: g.string().optional(),
});

const userMutationType = g.type('Mutation', {
    register: g.ref(userType)
        .args({
            email: g.string().required(),
            password: g.string().required(),
            name: g.string().optional()
        })
        .description('Register a new user')
});

const userQueryType = g.type('Query', {
    me: g.ref(userType)
    .extend({             // <-- extend the user type with additional fields
        createdAt: g.string(),
        updatedAt: g.string()
    })
        .description('User who is currently logged in')
})

This issue pertains to the userQueryType object and proposes extending it to include additional fields, createdAt and updatedAt, without duplicating the schema definition.

@mishushakov
Copy link
Member

mishushakov commented Mar 8, 2023

Hey Mubarak, thanks for starting the issue 😁
Why not use interfaces instead? Any scenario, where your approach could be more useful?

const userExtend = g.interface('UserExtend', {
  createdAt: g.string(),
  updatedAt: g.string()
});

const userType = g.type('User', {
  id: g.string(),
  email: g.string(),
  name: g.string().optional(),
}).implements(userExtend)

@iamshabell
Copy link
Author

Hi Mish! Thanks for your comment and suggestion. Using interfaces is certainly another way to extend the schema definition without duplicating the fields. In this case, we chose to use the extend method because it allows us to keep the schema definition in one place (userType object) and extend it only where necessary (userQueryType object).

However, I can see how using interfaces can be useful in some scenarios, especially if we have multiple types that need to share the same extended fields. It's always good to have multiple options and use the one that fits the situation best.

Thanks again for your input!

@mishushakov
Copy link
Member

mishushakov commented Mar 8, 2023

The problem is that you would end up extending the types here and there and then question yourself, why does the userType suddenly have x and y fields and where do they even come from? Then you will have to search all of your code to find that it's the userQueryType that did that

We can accept it as a schema manipulation utility, but not as a user-facing tool that we would suggest using
We will have to update the interface implementation anyways and this is where your effort could be more useful (You can then add your extend method later)

@mishushakov
Copy link
Member

The GraphQL spec describes a concept of extensions. We will have to support it as well, if we want to be compatible with the spec

https://spec.graphql.org/October2021/#sec-Object-Extensions

I will update my implements feature and once it is ready, you can try to add the extend to the types that support extensions, namely: object type, interface type, union, enum, input

@mishushakov
Copy link
Member

Added in 0.6.3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants