hayes / pothos

Pothos GraphQL is library for creating GraphQL schemas in typescript using a strongly typed code first approach
https://pothos-graphql.dev
ISC License
2.31k stars 155 forks source link

Extending objects #935

Open mmahalwy opened 1 year ago

mmahalwy commented 1 year ago

This could be placed in the "Patterns" section of the doc but curious if there is best practices or potential future support for extending an object (which would create a new one) instead of using interfaces. My thinking is:

const UserObject = builder.objectRef<{
  email: string;
  address?: string
}>('User').implement({
  fields: t => ({
    email: t.exposeString('email'),
    address: t.exposeString('address', { nullable: true })
  })
});

const UserWithAddressObject = UserObject.extend<{
  address: string;
}>('UserWithAddress').implement({
  fields: t => ({
    address: t.exposeString('address')
  })
});

As a result, the UserWithAddressObject would interface with the previous one. On a graphql schema, these are 2 separate objects. This is a bit different from graphql interfaces which tend to have the common fields on the interface and have objects extend. This can be achieved with interfaces with:

const UserInterface = builder.interfaceRef<{email: string}>('UserInterface').implement({
  fields: t => ({
    email: t.exposeString('email')
  })
})

const UserObject = builder.objectRef<{
  email: string;
  address?: string
}>('User').implement({
  interfaces: [UserInterface],
  fields: t => ({
    address: t.exposeString('address', { nullable: true })
  })
});

const UserObjectWithAddress = builder.objectRef<{
  email: string;
  address: string;
}>('UserWithAddress').implement({
  interfaces: [UserInterface],
  fields: t => ({
    address: t.exposeString('address')
  })
});
hayes commented 1 year ago

Patterns like this will be easier to build in v4, which is in progress, but I haven't had much time lately to work on it. V4 pushes all of the configs and field definitions into the refs, which makes it easier to add methods on refs that allow extending or mutating them.

There aren't any concrete plans for a feature like this, but making things more modular and extensible was part of the goal for v4

mmahalwy commented 1 year ago

Oh interesting. Didnt know there's a v4 in progress. Will check it out!

hayes commented 1 month ago

I know its been a lot longer than expected, but v4 is out now. It doesn't address this directly, but as mentioned before, it should enable this kind of feature. I have some other things that are higher priority for me right now (hoping to get a drizzle plugin out next), but if you are still interested in this, I'd be happy to help you get something implemented