ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.07k stars 723 forks source link

Schema Reloading without app restart - Headless CMS #6113

Open hnazari13701371 opened 1 year ago

hnazari13701371 commented 1 year ago

Product

Hot Chocolate

Is your feature request related to a problem?

hi , i want to design and develop a headless cms . one of the first thing this kind of app is that an end user use data modeler to model their needs but when they create their model i need also change the schema base on changes . i wonder how i can accomplish what i describe above thanks

The solution you'd like

whenever user change model my schema change on the fly

maxnatamo commented 1 year ago

I've been looking for something similar. It would technically be possible by using the ITypeModule-interface and generate new types on the fly. However, I don't know if there's any way to create ObjectTypeDefinition-instances from a C# type, which would simplify it a lot. The alternative is to write field-descriptors manually, which would be a great pain.

It seems there is a really easy solutions already. If you return an empty list from ITypeModule.CreateTypesAsync, it will force a reload of the models (an eviction):

nternal static class ApplicationUpdateHandler
{
    public static event EventHandler? ApplicationUpdated;

    public static void UpdateApplication(Type[]? updatedTypes)
    {
        ApplicationUpdated?.Invoke(null, EventArgs.Empty);
    }
}

internal sealed class HotReloadTypeModule : ITypeModule
{
    public HotReloadTypeModule()
    {
        ApplicationUpdateHandler.ApplicationUpdated +=
            (s, e) => TypesChanged?.Invoke(this, EventArgs.Empty);
        ;
    }

    public event EventHandler<EventArgs>? TypesChanged;

    public ValueTask<IReadOnlyCollection<ITypeSystemMember>> CreateTypesAsync(
        IDescriptorContext context, CancellationToken cancellationToken)
    {
        // We do not generate any types here, as we just want to evict the
        // RequestExecutor and rebuild the original schema, by invoking TypesChanged.
        return ValueTask.FromResult<IReadOnlyCollection<ITypeSystemMember>>(
            Array.Empty<ITypeSystemMember>());
    }
}

Source: #5165