Skip to content

Add annotation to include extension function in schema #384

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

Closed
wants to merge 4 commits into from
Closed

Add annotation to include extension function in schema #384

wants to merge 4 commits into from

Conversation

de55
Copy link
Contributor

@de55 de55 commented Sep 26, 2019

📝 Description

An annotation @GraphQLExtensionFunction was added to include extension functions within the query.

Additional tests still need to be added. I wanted to get confirmation on adding this and on the syntax before continuing. My personal use case for this is that a lot of our code is autogenerated, and this allows me to add functionality to those classes.

Extension properties are not currently a part of this PR.

🔗 Related Issues

#383

@smyrick
Copy link
Contributor

smyrick commented Sep 26, 2019

Do we need to add this annotation? Can we modify the existing SubTypeMapper to be able to get extensions methods, and just load those when we are running the function builder?

Then you can still exclude with GraphQLIgnore

https://github.com/ExpediaGroup/graphql-kotlin/blob/9eee16b2497bd882f1b56201158b7192ae16aba8/graphql-kotlin-schema-generator/src/main/kotlin/com/expediagroup/graphql/generator/SubTypeMapper.kt

@de55
Copy link
Contributor Author

de55 commented Sep 26, 2019

It is feasible to do it without the annotation. You would need to search for public static functions and then add them to the schema for the class that is the first parameter.

I did it with the annotation just so it was backwards compatible. Also not sure if there would be a performance hit looping through the methods.

@smyrick
Copy link
Contributor

smyrick commented Sep 26, 2019

@de55 I am wondering now though if we want to encourage this at all. I know you have your specific use cases for adding more fields to autogenerated models but wouldn't it be better to redefine the GraphQL models as their own unique types so there is a separation layer of the GraphQL models from the models that are generated from I assume a downstream service.

@de55
Copy link
Contributor Author

de55 commented Sep 26, 2019

In my particular case, the auto generated code is specifically for the GraphQL service. This just allows some flexibility for object specific code.

The changes were easier to make by making the changes to the core package rather than implementing custom hooks, and I thought it might be helpful to others. But if you would prefer that it isn’t in this package, I can implement via custom hooks.

Also graphql officially supports an extended object, not sure if you would prefer the extension types have a specific syntax like:

https://www.apollographql.com/docs/graphql-tools/generate-schema/

const typeDefs = [`
schema {
query: Query
}

type Query {
bars: [Bar]!
}

type Bar {
id
}
,
type Foo {
id: String!
}

extend type Query {
foos: [Foo]!
}
`]

@dariuszkuc
Copy link
Collaborator

just a side note -> @de55 while the graphql-spec does support extension types, graphql-java currently does not (hence the workaround with @ExtendsDirective in federation). Personally I also don't think those extension functions should be marked as extended type in the schema.

I'm wondering whether including this annotation would make it somewhat confusing though - as I mentioned above federation has its own workaround to declare extended types and this annotation provides a way to add Kotlin extension function to the graph.

@smyrick
Copy link
Contributor

smyrick commented Sep 27, 2019

Yea, I am leaning toward not supporting it as it would cause lots of confusion of how to include something in a schema, plus I think it may be more useful to use extension method on your schema models to add extra functions in for server side only without having to @GraphQLIgnore everything.

@de55 You said that you can still do the Reflection in your hooks right? I think that is the best approach for now but if we have a need for this later or more people asking about it we can re-open this discussion

@de55
Copy link
Contributor Author

de55 commented Sep 27, 2019

@smyrick @dariuszkuc It turns out I was not able to implement it through the hooks because I needed access to the generator, which creates a circular reference. I instead implemented it by inheriting from SchemaGenerator and overriding the objectType and interfaceType functions.

The only issue with this approach is that FederatedSchemaGenerator is final, so I had to copy/paste the code from that to my custom generator. Would you mind if that is made an open class?

@dariuszkuc
Copy link
Collaborator

The only issue with this approach is that FederatedSchemaGenerator is final, so I had to copy/paste the code from that to my custom generator. Would you mind if that is made an open class?

No issue there. Feel free to submit a PR to open it up.

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

Successfully merging this pull request may close these issues.

3 participants