Running GraphQL query returns The ID `1` has an invalid format

Viewed 567

Following the Hot Chocolate workshop and after the 4th step, when running the query

query GetSpecificSpeakerById {
  a: speakerById(id: 1) {
    name
  }
  b: speakerById(id: 1) {
    name
  }
}

I'm getting the following error.

The ID `1` has an invalid format.

Also, the same error is thrown for all queries which have ID as a parameter, maybe this could be a hint, what to check, for me, a person, who just run the workshop it's still unclear.

Based on (not accepted) answer in similar question Error "The ID `1` has an invalid format" when querying HotChocolate, I've checked Relay and it's configuration and looks good.

DI

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton(CreateAutomapper());
    services.AddPooledDbContextFactory<ApplicationDbContext>(options => 
        options.UseSqlite(CONNECTION_STRING).UseLoggerFactory(ApplicationDbContext.DbContextLoggerFactory));
    services
        .AddGraphQLServer()
        .AddQueryType(d => d.Name(Consts.QUERY))
            .AddTypeExtension<SpeakerQueries>()
            .AddTypeExtension<SessionQueries>()
            .AddTypeExtension<TrackQueries>()
        .AddMutationType(d => d.Name(Consts.MUTATION))
            .AddTypeExtension<SpeakerMutations>()
            .AddTypeExtension<SessionMutations>()
            .AddTypeExtension<TrackMutations>()
        .AddType<AttendeeType>()
        .AddType<SessionType>()
        .AddType<SpeakerType>()
        .AddType<TrackType>()
        .EnableRelaySupport()
        .AddDataLoader<SpeakerByIdDataLoader>()
        .AddDataLoader<SessionByIdDataLoader>();
}

Speaker type

public class SpeakerType : ObjectType<Speaker>
{
    protected override void Configure(IObjectTypeDescriptor<Speaker> descriptor)
    {
        descriptor
            .ImplementsNode()
            .IdField(p => p.Id)
            .ResolveNode(WithDataLoader);
    }

    // implementation
}

And query itself

[ExtendObjectType(Name = Consts.QUERY)]
public class SpeakerQueries
{
    public Task<Speaker> GetSpeakerByIdAsync(
        [ID(nameof(Speaker))] int id, 
        SpeakerByIdDataLoader dataLoader,
        CancellationToken cancellationToken) => dataLoader.LoadAsync(id, cancellationToken);
}

But without a bit of luck. Is there something else, what could I check? The full project is available on my GitHub.

1 Answers

I see you enabled relay support on this project. The endpoint execpts a valid relay ID.

Relay exposes opaque IDs to the client. You can read more about it here: https://graphql.org/learn/global-object-identification/

In short, a Relay ID is a base64 encoded combination of the typename and the id.

To encode or decode in the browser you can simply use atob and btoa on the console.

So the id "U3BlYWtlcgppMQ==" contains the value

"Speaker
i1"

you can decode this value in the browser with btoa("U3BlYWtlcgppMQ==") and encode the string with

atob("Speaker
i1")

So this query will work:

query GetSpecificSpeakerById {
  a: speakerById(id: "U3BlYWtlcgppMQ==") {
    id
    name
  } 
}
Related