Coder Social home page Coder Social logo

Comments (24)

bzbetty avatar bzbetty commented on June 10, 2024 1

oh interesting, my error seems to be due to not wrapping the sample app in a namespace - that's really confusing!

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

i have a feeling the implementation doesn't like only querying for a single type, in the method MakeSelectWithDynamicType i defaulted back to the old code is validTypes < 2. Was for a mix of performance/safety reasons but I clearly missed this case.

Can you try add a second fragment type ?

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

@bzbetty Oooo, indeed, adding a second fragment type to the query makes the error go away! 🙂

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

That being said, when there are two fragments, the requested fields don't seem to be returned.

Code

public interface IUser { }

public class Employee : IUser
{
    public string Name { get; set; }
}

public class Owner : IUser
{
    public string Id { get; set; }
}

public class UsersContext : IUsersContext
{
    public List<IUser> Users { get; set; } = new()
    {
        new Employee
        {
            Name = "test employee"
        },
        new Owner
        {
            Id = "1111"
        }
    };
}

public interface IUsersContext
{
    public List<IUser> Users { get; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddCors();
        builder.Services.AddTransient<IUsersContext, UsersContext>();
        builder.Services.AddGraphQLSchema<IUsersContext>(options =>
        {
            options.AutoBuildSchemaFromContext = false;

            options.ConfigureSchema = (schema) =>
            {
                schema.AddUnion<IUser>("User", null);
                schema.Type<IUser>().AddAllPossibleTypes();

                schema.UpdateQuery(queryType =>
                {
                    queryType.ReplaceField(
                        "users",
                        db => db.Users,
                        null
                    );
                });
            };
        });

        var app = builder.Build();
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseCors(builder =>
        {
            builder
            .WithOrigins("*")
            .WithMethods("POST")
            .AllowAnyHeader();
        });
        app.UseEndpoints(endpoints => endpoints.MapGraphQL<IUsersContext>());
        app.Run();
    }
}

Query

{ users { ... on Employee { name } ... on Owner { id } } }

Result

{"data":{"users":[{},{}]}}

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

what happens if you also ask for typename?

{ __typename users { ... on Employee { name } ... on Owner { id } } }

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

Have a look at TestAutoUnion seems to be a basic working sample?
I thought I'd used Unions in my codebase somehwere, i'll have a dig tomorrow.

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

Actually is this the same field vs property serialization issue you had in #263 ?

from entitygraphql.

lukemurray avatar lukemurray commented on June 10, 2024

Shouldn't be the serialisation issue if running the above code as that is using the AddGraphQLSchema extensions which sets that up.

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

@bzbetty If I ask for typename, I get it back correctly.

Query

{
  users {
    __typename,
    ... on Employee { name },
    ... on Owner { id }
  }
}

Result

{
  "data": {
    "users": [
      {
        "__typename": "Employee"
      },
      {
        "__typename": "Owner"
      }
    ]
  }
}

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

@bzbetty I thought this might be a field serialization issue, too (since indeed, I just messed that up, haha 😆), but as @lukemurray says, in this example, I'm using AddGraphQLSchema().

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

What version are you running against? if I use your sample app against 4.0.1 i get quiet a different error

image

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

@bzbetty I'm running against commit 099aad8 🙂

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

If I do the following instead of passing the query via http it seems to return the value correctly.

                    var gql = new GraphQLCompiler(schema).Compile(@"
query {
   users {
      __typename
     ... on Employee { name },
    ... on Owner { id }
   }
}");
                    var context = new UsersContext();

                    var qr = gql.ExecuteQuery(context, null, null);
                    int i = 0;

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

with a breakpoint in DefaultGraphQLResponseSerializer i can confirm the data is on the object, it's just not serialized for some reason.

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

potentially related dotnet/runtime#31742

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

also this https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism?pivots=dotnet-6-0 - although I'm not seeing a fix

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

oh interesting, my error seems to be due to not wrapping the sample app in a namespace - that's really confusing!

Lol, that's surprising! 😆

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

@bzbetty Very interesting... and unexpected! 🙂

I guess in our case, the solution is simple: Use the Newtonsoft serializer, which is actually what we're using anyway... I just used the System.Json serializer in the example, since that lead to a shorter repro.

I does look like .NET 7 supports polymorphic serialization, but... ya... that'd required apps to be running .NET 7: https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism?pivots=dotnet-7-0

It look like we uncovered three bugs within this thread, haha.

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

BTW, I can confirm that this works fine when using the Newtonsoft serializer 🙂

from entitygraphql.

lukemurray avatar lukemurray commented on June 10, 2024

@Bosch-Eli-Black would you mind double checking against the master branch? Want to make sure there is not an edge case we have missed. Thanks

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

@lukemurray I'm afraid that made it a bit worse, haha 😄

Code

using EntityGraphQL.AspNet;

namespace Example;

public interface IUser { }

public class Employee : IUser
{
    public string Name { get; set; }
}

public class Owner : IUser
{
    public string Id { get; set; }
}

public class UsersContext : IUsersContext
{
    public List<IUser> Users { get; set; } = new()
    {
        new Employee
        {
            Name = "test employee"
        },
        new Owner
        {
            Id = "1111"
        }
    };
}

public interface IUsersContext
{
    public List<IUser> Users { get; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        builder.Services.AddCors();
        builder.Services.AddTransient<IUsersContext, UsersContext>();
        builder.Services.AddGraphQLSchema<IUsersContext>(options =>
        {
            options.AutoBuildSchemaFromContext = false;

            options.ConfigureSchema = (schema) =>
            {
                schema.AddUnion<IUser>("User", null);
                schema.Type<IUser>().AddAllPossibleTypes();

                schema.UpdateQuery(queryType =>
                {
                    queryType.ReplaceField(
                        "users",
                        db => db.Users,
                        null
                    );
                });
            };
        });

        var app = builder.Build();
        app.UseHttpsRedirection();
        app.UseRouting();
        app.UseCors(builder =>
        {
            builder
            .WithOrigins("*")
            .WithMethods("POST")
            .AllowAnyHeader();
        });
        app.UseEndpoints(endpoints => endpoints.MapGraphQL<IUsersContext>());
        app.Run();
    }
}

Query

{ users { __typename, ... on Employee { name } ... on Owner { id } } }

Result

[
    {
        "key": "data",
        "value": [
            {
                "key": "users",
                "value": [
                    {},
                    {}
                ]
            }
        ]
    }
]

Tested with d65435f

from entitygraphql.

bzbetty avatar bzbetty commented on June 10, 2024

PR should now return

{
  "data": {
    "users": [
      {
        "name": "test employee",
        "__typename": "Employee"
      },
      {
        "id": "1111",
        "__typename": "Owner"
      }
    ]
  }
}

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

@bzbetty Thanks!

Will test tomorrow, God willing 🙂

from entitygraphql.

Eli-Black-Work avatar Eli-Black-Work commented on June 10, 2024

@bzbetty and @lukemurray It works! Thank you! ^_^

I've confirmed that both bugs that were discovered in this issue have been fixed 🙂

Thanks again! 🙂

from entitygraphql.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.