Closed mohammad-al-mahamid closed 1 month ago
That is what the relay spec is about :) ID values are encoded into base64 to allow for global unique identifiers.
@michaelstaib
as an example the getSpeakers returns the ids as a base64 encoded string, when I try to find another speaker with a specific id I get the error "errors": [ { "message": "The specified argument value does not match the argument type.", "locations": [ { "line": 9, "column": 21 } ], "path": [ "speakerById" ], "extensions": { "argument": "id", "argumentValue": "\"U3BlYWtlcgppMQ== \"", "locationType": "Int!", "specifiedBy": "http://spec.graphql.org/October2021/#sec-Values-of-Correct-Type" } } ] }
I have solved this problem by adding "[ID]" to the queries:
public Task<Speaker> GetSpeakerByIdAsync([ID(nameof(Speaker))] int id, SpeakerByIdDataLoader speakerByIdDataLoader, CancellationToken cancellationToken) => speakerByIdDataLoader.LoadAsync(id, cancellationToken);
but I also face this problem when I try to add a new session, here the ids would not be accepted in the base64 encoding, The error:
{ "errors": [ { "message": "Int cannot parse the given literal of type
StringValueNode.", "path": [ "input", "speakerIds", 0 ], "extensions": { "field": "AddSessionInput.speakerIds", "fieldType": "Int" } } ] }
how to solve this problem? and is there a way to avoid the base64-encoding?
You probably already resolved this, but for those having this same issue. When writing the *Input
records, do not use parameters, use properties like so
public record AddSessionInput
{
public string Title { get; set; }
public string? Abstract { get; set; }
[ID(nameof(Speaker))] public IReadOnlyList<int> SpeakerIds { get; set; }
}
I do not know the reason, but by using parameters the global identifiers (ID
) will still be int
s. By rewriting the records to have properties, the global identifiers (ID
) will take the base64 id encodings.
I created a blog post with all the fixes/upgrades to work with the latest Hot Chocolate and .NET 7 and minimal APIs https://esausilva.com/2023/04/12/solved-graphql-hot-chocolate-workshop-issues-updated/
@esausilva
You can also use [property: ID<Speaker>]
to target the property, for example:
public sealed record AddSessionInput(
string Title,
string? Abstract,
[property: ID<Speaker>] IReadOnlyList<int> SpeakerIds);
I'm closing this issue as outdated, as we have an updated workshop on the main
branch, for Hot Chocolate 14.
The ID is stored as a Guid in my database, but when queried through GraphQL, it is returned as a base64 encoded string. i am facing this problem after enabling relay policy and implementing the reolver to improve data fetch. Is there a way to configure a custom serializer or scalar type for Guid values in the schema?