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.03k stars 723 forks source link

UseFiltering() fails with Azure Function host #1333

Closed b-twis closed 2 years ago

b-twis commented 4 years ago

Hi All,

Describe the bug Azure Function Filteirng Exception is raised for Implicit Filtering.

System.InvalidOperationException: 'No coercion operator is defined between types 'System.Object' and 'System.Void'.'

If I add a Explicit Filtering Type it seems to be ok. However I do not want to have to define the explicit filters everywhere.

To Reproduce Using Repository located https://github.com/OneCyrus/GraphQL-AzureFunctions-HotChocolate

Steps to reproduce the behavior:

  1. Download the above sample repository.

  2. Install NuGet package for HotChocolate.Types.Filters 10.3.0

  3. Update QueryType.cs to add UseFiltering() to the first field for GetHero.

protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
        {
            descriptor.Field(t => t.GetHero(default))
                .Type<CharacterType>()
                .Argument("episode", a => a.DefaultValue(Episode.NewHope))
                .UseFiltering();

            descriptor.Field(t => t.GetCharacter(default, default))
                .Type<NonNullType<ListType<NonNullType<CharacterType>>>>()
                .Argument("characterIds",
                    a => a.Type<NonNullType<ListType<NonNullType<IdType>>>>());

            descriptor.Field(t => t.GetHuman(default))
                .Argument("id", a => a.Type<NonNullType<IdType>>());

            descriptor.Field(t => t.GetDroid(default))
                .Argument("id", a => a.Type<NonNullType<IdType>>());
        }
  1. Run a standard unrelated query
{
    droid (id:2000) {
        id,
        name,
        friends  {
            name

        }
    }
}

Error message

Executed 'graphql' (Failed, Id=1de29352-d7cd-4282-9858-67626a82d8c1)
[07/01/2020 13:47:46] HotChocolate.Types: Unable to create instance of type `HotChocolate.Types.Filters.FilterInputType`1[[StarWars.Models.ICharacter, GraphQL-AzureFunctions-HotChocolate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]`.
[07/01/2020 13:47:46] An unhandled host error has occurred.
[07/01/2020 13:47:46] HotChocolate.Types: Unable to create instance of type `HotChocolate.Types.Filters.FilterInputType`1[[StarWars.Models.ICharacter, GraphQL-AzureFunctions-HotChocolate, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]`.

Which seems to comes from an internal exception (as seen in Preview of VS 2019) System.InvalidOperationException: 'No coercion operator is defined between types 'System.Object' and 'System.Void'.'

Desktop (please complete the following information): OS: Windows 10 Visual Studio Community 2019 .Net Core 3.0 Azure Runtime v3

Any assistance would be greatly appreciated.

michaelstaib commented 4 years ago

To me this looks like there is a method inferred that returns null instead of something. Do you mind sharing a repro?

b-twis commented 4 years ago

@michaelstaib You should be able to take the one I linked and make the same change I did.

michaelstaib commented 4 years ago

sorry :) skimmed the text :D

OneCyrus commented 4 years ago

I'm looking into this now. the issue is with GetService in https://github.com/ChilliCream/hotchocolate/blob/fafbac232b86a3a0fb48090a2cffff735e2253e8/src/Core/Utilities/ServiceFactory.cs#L143

GetService throws an exception in Azure Functions when it doesn't find something in the DI container. In Asp.Net Core it returns null. I'm in talk with Microsoft if this behaviour is really intended that way and if they don't want to align it.

PascalSenn commented 4 years ago

@OneCyrus https://docs.microsoft.com/en-us/dotnet/api/system.iserviceprovider.getservice?view=netcore-3.1 image

michaelstaib commented 4 years ago

This means they implemented it in a wrong way for functions

ragnarls08 commented 4 years ago

Any word on this? workaround?

Am I correct in assuming Filtering/Pagination is not currently working in azure functions.

michaelstaib commented 4 years ago

This is actually a bug with the azure functions di since the IServiceProvider interfaces explicitly states that null shall be returned if a service does not exist.

@OneCyrus what is the status on this?

We could create a workaround if ms is not fixing this. But lets wait for Daniel to give a status.

OneCyrus commented 4 years ago

they don't feel the urge to fix this behaviour. so there won't be a proper fix anytime soon.

michaelstaib commented 4 years ago

Is that open source?

OneCyrus commented 4 years ago

yes, though the issue is a bit complex. it only happens when hosting a real function and the issue is not there when testing in the functions host itself.

https://github.com/Azure/azure-functions-host/tree/dev/src/WebJobs.Script.WebHost/DependencyInjection/DryIoc

michaelstaib commented 4 years ago

I think I will rewrite the dependency injection integration if hc so that we never need to fetch services that do not exist... For ms to fix that will take to long.

timjroberts commented 4 years ago

This issue appears to be present for any InputObjectType. Would this mean that HotChocolate hosted in Azure Functions is not viable for the moment, since you'd need InputObjectType's to define mutations?

michaelstaib commented 4 years ago

No it works quite well in auf. There is a Starwars example that shows all the typical stuff is working. Also the issues with the di for filtering works.

michaelstaib commented 4 years ago

Best get on the slack channel and ask general

timjroberts commented 4 years ago

Sorry, which example? The one on this repo's master branch appears incomplete. The function body is empty. The one at https://github.com/OneCyrus/GraphQL-AzureFunctions-HotChocolate is complete but only has a Query type. The Review and ReviewInputType aren't used in the project.

Please don't think that I'm being awkward or anything like that. I've used HotChocolate before and it's brilliant. Have a need to use it with Azure Functions at the moment and can't seem to get a complete solution working. Will join the Slack.

PascalSenn commented 4 years ago

@timjroberts AzF may have restrictions. The examples of @OneCyrus is working though. The IServiceProvider of AzF works differently from the one of .net core. GetService works like GetRequiredService this breaks the contract of IServicePrivder and is a challenge. These issues are already solved by @OneCyrus I think . Then there is the cold start of AzF that might not be ideal for a GraphQL API. We will put some effort into AzF eventually but are quite busy at the moment with other features. Join slack, we will help you to connect to people that have used HC on AzF 👍

lakshmi-is commented 3 years ago

Hi All, Facing an issue with UseFiltering in azure function app..Giving an error like "Unable to create instance of type `HotChocolate.Types.Filters.FilterInputType" Please help me regarding this.

Thanks

Deathrage commented 3 years ago

Hi, this issue can be fixed by replacing default IServiceProvider implementation for your own. You can either implement it by yourself or use for example AutoFac: https://github.com/junalmeida/autofac-azurefunctions

Changing the IServiceProvider will fix the issue as you can make it behave accordingly.

Even though IFunctionsHostBuilder has only one property Services it's still easy to sneak in your own IServiceProvider as IServiceCollection holds registration for singletons IJobActivatorand IJobActivatorEx which are used to invoke the Functions and resolve their dependencies, so you can simply replace them. Even though the DefaultJobActivator is internal, you can still copy it's interiors as it's quite simple (by default it holds instance of IServiceProvider and resolve Functions using it). So if you do not want to you AutoFac's solution you can make your own.

This will not change IServiceProvider globally, but it will change the IServiceProvider that is used by IJobActivator to invoke the Function

PascalSenn commented 2 years ago

We now have a template for azure functions and this issue should be resolved:

dotnet new -i HotChocolate.Templates   
dotnet new graphql-azf