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

Add support for the default interface method implementation #7030

Open
livwvil opened this issue Mar 29, 2024 · 0 comments
Open

Add support for the default interface method implementation #7030

livwvil opened this issue Mar 29, 2024 · 0 comments
Labels

Comments

@livwvil
Copy link

livwvil commented Mar 29, 2024

Product

Hot Chocolate

Is your feature request related to a problem?

Lets imagine we want the Hot Chocolate to produce a schema like:

interface IChannel {
  id: ID!
  description: String!
  status: ChannelStatus!
}

union IAnotherChannel = ChannelTypeB | ChannelTypeC

type ChannelTypeA implements IChannel {
  id: ID!
  description: String!
  status: ChannelStatus!
  ip: String!
}

type ChannelTypeB implements IChannel {
  id: ID!
  description: String!
  status: ChannelStatus!
  port: String!
}

type ChannelTypeC implements IChannel {
  id: ID!
  description: String!
  status: ChannelStatus!
  adapter: String!
}

I have to use records in my project. So I did somethink like:

[GraphQLName("IChannel")]
public interface IChannelDto
{
    [ID]
    Guid Id { get; init; }

    string Description { get; init; }

    #region workaround
    // TODO: delete after Hot Chocolate Team fixes one of two issue:
    // - ExtendObjectType should extend interface and all derived classes
    // - interface default methods implementations must be used in derived classes
    Task<ChannelStatus> GetStatusAsync() { throw new NotImplementedException(); }
    #endregion
}

[ExtendObjectType(typeof(IChannelDto))]
public class ChannelResolvers
{
    public async Task<ChannelStatus> GetStatusAsync()
    {
        // Do some stuff
    }
}

[GraphQLName("ChannelTypeA")]
public record ChannelTypeADto
(
    [property: ID] Guid Id,
    string Description,
    string IP,
) : IChannelDto;

[UnionType("IAnotherChannel")]
public interface IAnotherChannelDto : IChannelDto { };

[GraphQLName("ChannelTypeB")]
public record ChannelTypeBDto
(
    [property: ID] Guid Id,
    string Description,
    string Port,
) : IAnotherChannelDto;

[GraphQLName("ChannelTypeC")]
public record ChannelTypeCDto
(
    [property: ID] Guid Id,
    string Description,
    string Adapter,
) : IAnotherChannelDto;

Here is a problem:

  1. The ExtendObjectType annotation does not extend interfaces by design but I need it, so I made a workaround. That stub function is never called and I only need it to create the schema.
  2. I can't just remove the class with the ExtendObjectType annotation and put the default implementation inside the interface. Hot chocolate want me to add a Status field inside all derived records.

I must use both the ExtendObjectType annotation and that stub default implementation in the interface. If I could replace records with classes, I would do something like:

[InterfaceType("IChannel")]
public abstract class ChannelDto
{
    [ID]
    public Guid Id { get; init; }

    public string Description { get; init; }

    public async Task<ChannelStatus> GetStatusAsync()
    {
        // Do some stuff
    }
}

[GraphQLName("ChannelTypeA")]
public class ChannelTypeADto : ChannelDto
{
    public string IP { get; init; }
}

[UnionType("IAnotherChannel")]
public abstract class AnotherChannelDto : ChannelDto { };

[GraphQLName("ChannelTypeB")]
public class ChannelTypeBDto : AnotherChannelDto
{
    public string Port { get; init; }
}

[GraphQLName("ChannelTypeC")]
public class ChannelTypeCDto : AnotherChannelDto
{ 
    public string Adapter { get; init; }
}

This works nice!

The solution you'd like

One of:

  1. Let the ExtendObjectType annotation extend interfaces.
  2. Add support for the default method implementation in the schema inference algorithm.
@livwvil livwvil added the 🎉 enhancement New feature or request label Mar 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants