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

Gradle Plugin Doesn't Generate Federation Directives #2242

Open
kartomic8 opened this issue Dec 16, 2024 · 5 comments
Open

Gradle Plugin Doesn't Generate Federation Directives #2242

kartomic8 opened this issue Dec 16, 2024 · 5 comments

Comments

@kartomic8
Copy link

kartomic8 commented Dec 16, 2024

When using the Gradle Plugin (v2.6.2), the output of the generateSchema gradle task does not appear to generate federation-compatible directives.

Sample code:

generateSchema {
    destination = "build/generated/schema.graphql"
    includeTransitiveDependencies = true
    includeDirectives = true
    includeScalars = true
}
// Example of annotated class
@Data
@AllArgsConstructor
@Shareable
public class Menu {
  @NonNull List<MenuItem> menuItems;
}
# generated graphql
# expected @shareable directive in the line below, but it is not there:

type Menu {
  menuItems: [MenuItem]!
}


# In addition, the federation directives aren't imported, nor are they defined in the output.

I took a look at the maven plugin, which does appear to implement federation, and I can't find similar code in the gradle plugin, so I believe its just not implemented. Can the team confirm, and if it isn't implemented advise on a timeframe for doing so?

@jmartisk
Copy link
Member

Hi, currently the plugin assumes that it should enable Federation if at least one of these conditions is true:

If this is not good enough, we welcome suggestions on how to improve it

@kartomic8
Copy link
Author

Thanks for responding. @jmartisk, looks like most of it was user error, enabling the appopriate settings resulted in those directives being added to the schema. However, there's one thing I wanted to inquire about that we weren't able to figure out. We're using the Apollo Federated Router in our environment, and from playing around with it it seems to want us to import directives rather than redefine them.

E.g. This works with apollo router:

extend schema
  @link(url: "https://specs.apollo.dev/federation/v2.7",
        import: ["@key"]) {
  query: Query
  mutation: Mutation
}

But this generated output from the smallrye doesn't

"Designates an object type as an entity and specifies its key fields (a set of fields that the subgraph can use to uniquely identify any instance of the entity). You can apply multiple @key directives to a single entity (to specify multiple valid sets of key fields)."
directive @key(fields: FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE

Is there a way we can get the smallrye-graphql library to emit the extend schema style of importing directions from the federation spec?

@jmartisk
Copy link
Member

Hmm I don't think we support that right now, and my knowledge of Federation doesn't cover this. Maybe @t1 or @RoMiRoSSaN know if the federation-jvm library supports this style?

@kartomic8
Copy link
Author

kartomic8 commented Jan 13, 2025

Any help would be appreciated. FYI, I am also in contact with Apollo on this issue, and they did confirm that the spec technically does require this directive to be included. Its not documented on their subgraph spec page, but is documented on their "versions" page: (https://www.apollographql.com/docs/graphos/reference/federation/versions). When I pointed this out, they mentioned they would add a backlog item to update their subgraph spec to include this info.

They also provided me with the following information:

federation-jvm is primarily for the (most popular) SDL first libs [...] as it transforms provided schema files to add missing definitions. With code first libraries, they often redefine those directives as they are driven by the corresponding code usages. We do expose public static List<SDLNamedDefinition> loadFederationSpecDefinitions(string federationSpec) (link)` but hard to say whether this would be useful for [their implementation]

Does it make sense for me to open a separate issue requesting this be implemented in smallrye? Although we can workaround by modifying the output of the gradle task, future developers using the Apollo Federated Router and smallrye would benefit from this.

@RoMiRoSSaN
Copy link
Contributor

Hi @kartomic8, If I understand correctly, you need to do something similar in the code

// Create empty api class, annotate it @Link like this, use @Import
@GraphQLApi
@Link(url = FEDERATION_SPEC_LATEST_URL, _import = {@Import(name = "@key")})
public class LinkResource {
}

// example class with federation directives
@Key(fields = @FieldSet(value = "id"))
public record Model(Long id) {
}

// any api class
@GraphQLApi
public class HelloGraphQLResource {
    @Query
    @Description("Say hello")
    public Model sayHello() {
        return new Model(1L);
    }
}

Use next config

quarkus.smallrye-graphql.schema-include-scalars=true
quarkus.smallrye-graphql.schema-include-directives=true
quarkus.smallrye-graphql.federation.enabled=true
quarkus.smallrye-graphql.schema-include-schema-definition=true

After this, schema will be like

schema @link(import : ["@key"], url : "https://specs.apollo.dev/federation/v2.7"){
  query: Query
}

// if not included in @Import annotation
directive @federation__tag(name: String!) repeatable on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION

// if included in @Import annotation
directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE

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

// other directives

union _Entity = Model

type Model @key(fields : "id") {
  id: BigInteger
}

"Query root"
type Query {
  _entities(representations: [_Any!]!): [_Entity]!
  _service: _Service!
  sayHello: Model
}

'@link' and others directives were added in version 2.8.0, use it or higher.
Use plugin 2.11.0 version or higher. it contains fixes for correct schema generation with next config

generateSchema {
    includeScalars = true
    includeDirectives = true
    includeSchemaDefinition=true
}

Code example for test - demo2.zip

Only one moment - will be generated schema ..., not extend schema .... but I tested the work of Apollo, and it worked without extend

Please, check it

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

No branches or pull requests

3 participants