apollographql / federation-hotchocolate

HotChocolate support for Apollo Federation
https://www.apollographql.com/docs/federation/
MIT License
16 stars 8 forks source link

@link directive is missing when using hotchocolate authorization #55

Open rohinz opened 12 months ago

rohinz commented 12 months ago

Adding HotChocolate.AspNetCore.Authorization to the schema removes the @link directive from the schema.

How to reproduce

  1. create a graphql schema with federation support
using ApolloGraphQL.HotChocolate.Federation;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddGraphQLServer()
    .AddApolloFederationV2()
    .AddQueryType<Query>();

var app = builder.Build();

app.MapGraphQL("/");
app.RunWithGraphQLCommands(args);

public class Query
{
    public User GetUser() => new("1", "David");
    [ReferenceResolver]
    public User ResolveUser(string id) => new(id, "David");
}

[Key("id")]
public record User(string Id, string Name);
  1. print the schema with dotnet run -- schema export

the schema contains the @link directive

schema @link(url: "https:\/\/specs.apollo.dev\/federation\/v2.5", import: [ "@extends", "@external", "@key", "@inaccessible", "@override", "@provides", "@requires", "@shareable", "@tag", "FieldSet", "@composeDirective", "@interfaceObject" ]) {
  query: Query
}

type Query {
  user: User!
  resolveUser(id: String!): User!
  _service: _Service!
  _entities(representations: [_Any!]!): [_Entity]!
}
...
  1. add HotChocolate.AspNetCore.Authorization nuget and add authorization to the schema builder:
using ApolloGraphQL.HotChocolate.Federation;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddGraphQLServer()
    .AddApolloFederationV2()
    .AddAuthorization()
    .AddQueryType<Query>();

var app = builder.Build();

app.MapGraphQL("/");
app.RunWithGraphQLCommands(args);

public class Query
{
    public User GetUser() => new("1", "David");
    [ReferenceResolver]
    public User ResolveUser(string id) => new(id, "David");
}

[Key("id")]
public record User(string Id, string Name);
  1. print the schema again with dotnet run -- schema export

Expectation

Current Behavior

schema {
  query: Query
}

type Query {
  user: User!
  resolveUser(id: String!): User!
  _service: _Service!
  _entities(representations: [_Any!]!): [_Entity]!
}
dariuszkuc commented 12 months ago

Hello 👋 I believe this is due to the limitations of the existing HC TypeInterceptor API (that 🤞 will be fixed in their replacement "skimmed" API which is still WIP). Underlying issue is that current HC API is somewhat finicky and depending on the order of processed items you can have side effects that break other things. AFAIK currently it is not possible to apply multiple schema transformations (see: https://github.com/ChilliCream/graphql-platform/issues/6651) so you only get the results of applying the last transformation.

Since the @link definitions are getting removed it looks like HotChocolate.AspNetCore.Authorization also attempts to change the schema object so you will only get the last transformation. You could try changing the order of the extension but I wouldn't be surprised if your HC authorization logic stops working in that case, i.e.

builder.Services
    .AddGraphQLServer()
    .AddAuthorization()
    .AddApolloFederationV2()
    .AddQueryType<Query>();
cli00004 commented 10 months ago

@dariuszkuc Changing order still resulted in same behaviour (@link missing) which resulted in federation compatibility issue