0

I have the following code designed to apply a list of errors to resolved items by fetching the full list of errors from another service which that caches them for performance reasons:

public class MyEntityExtensions : ObjectType<MyEntity>
{
    protected override void Configure(IObjectTypeDescriptor<MyEntity> descriptor)
    {
        descriptor
            .Field("errors")
            .Type(typeof(List<Error>))
            .Resolve(async context =>
            {
                var errorCache = context.Service<ErrorCache>();

                var entityId = ???;

                var errors = await errorCache.Get(entityId);

                return errors ;
            });
    }
}

How can I get the Id property of the current Entity to pass as the argument to the cache?

For a declarative approach, there doesn't seem to be any way to enforce resolver order or declare dependencies between fields. For a runtime approach, there doesn't seem to be any property on the MiddlewareContext that holds any information related to other fields on the same object. The only way to reference a resolved item seems to be .Parent<> but this isn't a hierarchy.

I've tried several different approaches to setting up this middleware and several ways of trying to manipulate order of operations via the .Use() method but no luck.

Is this possible with the current approach? If not, is there another approach that doesn't require stitching the errors as a completely separate data source?

JRoughan
  • 1,635
  • 12
  • 32
  • I should note that I've tried to use descriptor.BindFieldsImplicitly() and other methods to ensure Id is available at the point it's needed, but these haven't worked. – JRoughan Aug 25 '23 at 04:22

1 Answers1

0

You can use context.Parent like this:

public class MyEntityExtensions : ObjectType<MyEntity>
{
    protected override void Configure(IObjectTypeDescriptor<MyEntity> descriptor)
    {
        descriptor
            .Field("errors")
            .Type(typeof(List<Error>))
            .Resolve(async context =>
            {
                var errorCache = context.Service<ErrorCache>();

                var entityId = context.Parent<MyEntity>().Id; // Here

                var errors = await errorCache.Get(entityId);

                return errors ;
            });
    }
}
Joundill
  • 6,828
  • 12
  • 36
  • 50
  • I tried using Parent but it returns an entity with default properties (i.e. Id = 0). Reading up more on that approach seems to indicate that Parent will only be populated in a hierarchy such as `class Entity { List Children; }` – JRoughan Aug 25 '23 at 04:06
  • You might be doing something funky outside of the code you supplied. What happens if you add the `Id` field to your descriptor, then attempt to retrieve it with GraphQL? `descriptor.Field("Id")` – Joundill Aug 25 '23 at 05:30
  • The existing resolver is just a passthrough to an EntityFramework DBSet. The only funkiness is some middleware to extract JWT claims, which I disabled as part of trying to isolate the issue. The Id property is returned correctly when queried over GraphQL without the middleware, with the middleware as shown, and when explicitly or implicitly bound in the middleware. It just doesn't seem to be *accessible* within the middleware. – JRoughan Aug 25 '23 at 05:44