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

Bug: HC 14.0.0-p.98 prevents Relay IDs from working when a custom ID class or record is used #7098

Closed
Jlopez2045 opened this issue May 10, 2024 · 7 comments

Comments

@Jlopez2045
Copy link

Product

Hot Chocolate

Version

14.0.0-p.98

Link to minimal reproduction

https://github.com/Jlopez2045/RelayCustomIdIssue

Steps to reproduce

Run following query:

query {
    products {
        id
        name
    }
}

What is expected?

{
    "data": {
        "products": [
            {
               "id": "UHJvZHVjdDox"
                "name": "Book"
            }
        ]
    }
}

What is actually happening?

{
    "errors": [
        {
            "message": "Cannot return null for non-nullable field.",
            "locations": [
                {
                    "line": 2,
                    "column": 5
                }
            ],
            "path": [
                "products"
            ],
            "extensions": {
                "code": "HC0018"
            }
        },
        {
            "message": "No serializer registered for type `Product`.",
            "extensions": {
                "typeName": "Product"
            }
        }
    ],
    "data": null
}

Relevant log output

No response

Additional context

Upgraded from 14.0.0-p.82

@michaelstaib
Copy link
Member

Actually we now support a much better way to support these things ... you can now implement your own optimized value serializers for these. However, in the next couple of builds the source generator will also offer automatic generation of these.

@michaelstaib
Copy link
Member

This shows the composite ID serializer ....

protected override NodeIdFormatterResult Format(Span<byte> buffer, CompositeId value, out int written)

these must be registered with AddNodeIdValueSerializer ....

However ... with the next couple of builds there will be auto generation and auto registration.

@livwvil
Copy link

livwvil commented Jul 30, 2024

.AddLegacyNodeIdSerializer() helped me

@mmccord-processunity
Copy link

mmccord-processunity commented Sep 26, 2024

This appears to still be present in the latest of the 14.x line, even with AddLegacyNodeIdSerializer or with adding a custom INodeIdValueSerializer. @michaelstaib

@tobias-tengler
Copy link
Collaborator

I'm 100% confident that it works, because I migrated our custom Ids at work to the new serializers.
Can you share how you configure, register and use one of your custom Ids?

@tomachristian
Copy link

I am doing this:

Image

And still not able to use WorkflowId as a global object identifier...

@tobias-tengler
Copy link
Collaborator

You need to implement an INodeIdValueSerializer or you can use CompositeNodeIdValueSerializer if you just want to chain some Id "parts" using :.

internal sealed class ProductIdentifierNodeIdValueSerializer : CompositeNodeIdValueSerializer<ProductIdentifier> {
    protected override NodeIdFormatterResult Format(Span<byte> buffer, ProductIdentifier value, out int written) {
        if (TryFormatIdPart(buffer, value.Part1, out var writtenPart1Length) 
            && TryFormatIdPart(buffer.Slice(writtenPart1Length), value.Part2, out var writtenPart2Length)) {
             written = writtenPart1Length + writtenPart2Length;
             return NodeIdFormatterResult.Success;
        }

        written = 0;
        return NodeIdFormatterResult.BufferTooSmall;
    }

    protected override bool TryParse(ReadOnlySpan<byte> buffer, out ProductIdentifier value) {
        if (/* your parsing logic */) {
          // successfully parsed
          value = parsedValue;
          return true;
       }

      // failed to parse
      return false;
    }
}

Then you need to register the serializer.

private static IRequestExecutorBuilder AddStronglyTypedIds(
    this IRequestExecutorBuilder builder) {
    builder
        .AddNodeIdValueSerializer<ProductIdentifierNodeIdValueSerializer>()
        .BindRuntimeType<ProductIdentifier, IdType>();
}

Hope this helps :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants