apollographql / federation-jvm

JVM support for Apollo Federation
https://www.apollographql.com/docs/federation/
MIT License
250 stars 65 forks source link

'link' directive definition is missing 'for' parameter #351

Closed kbrooks closed 1 year ago

kbrooks commented 1 year ago

The directive definitions for link are missing the for parameter. This causes issues with code generation using graphql-code-generator if you're trying to merge two federated schemas.

Why am I doing that instead of using the federated gateway? Because it's a migration. I need to be able to turn on federation for my different services while maintaining the old way of accessing them via separate clients and using the combined schema generated by graphql-code-generator.

    Failed to load schema from https://[service1],https://[service2]:

            Unable to merge GraphQL directive "link".
    Existing directive:
        directive @link(url: String!, as: String, import: [link__Import]) on SCHEMA
    Received directive:
        directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) on SCHEMA

The link specification is here https://github.com/apollographql/specs/blob/cd50674b4c982766f2e62ee0a00dc04fecf95f42/link/v1.0/link-v1.0.graphql#L5C1-L10

The directive is defined like this inside federation-graphql-java-support (it's the same for all versions): https://github.com/apollographql/federation-jvm/blob/7b1c4bc32736e861815883cd3c84916d6e816d4d/graphql-java-support/src/main/resources/definitions_fed2_0.graphqls#L40-L44

dariuszkuc commented 1 year ago

Thanks for raising this. We indeed did not implement handling of Purpose enum as it is used only internally by gateway/router when constructing a supergraph (as in subgraphs should "never" define it as it is useless information for them, i.e. it would always be null)). That being said, for completeness we should handle it.

Somewhat curious on why your graphs define it?

kbrooks commented 1 year ago

So my issue is due to graphql code generator's schema merging feature not knowing what to do with the differently defined federation-related stuff in my two schemas I'm preparing to move into the apollo federated gateway. I was able to fix the issue by adding the directives etc to the schema file itself

directive @link(url: String!, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA

scalar link__Import

enum link__Purpose {
    SECURITY
    EXECUTION
}

directive @federation__external(reason: String) on OBJECT | FIELD_DEFINITION

Adding the values directly to the schema makes it so federation does not automatically add its own, and unblocks code generation.