Comments (11)
@liqweed You can access the name of the generatedType
since at this point in the hook, it is fully generated. You can also look at the info on the KType
but that is not always the most accurate if you are using this like @GraphQLName
to override the type name. You don't have to traverse any builder, but if you want to edit the type, you can pass it into a new builder and edit the fields that way to produce a new generated GraphQLType
@rharriso This hook can be used at this point to add any more info to the type, not just documentation. We already have a way to do custom directives, documented here: https://github.com/ExpediaDotCom/graphql-kotlin/wiki/Schema-Directives
The comment you are referring to is a way to expose a config method or setting to provide a list of pre-configured directives instead of using the onRewireGraphQLType
. There are slightly different issues.
from graphql-kotlin.
You can add custom documentation using @GraphQLDescription
annotation that can be added to any type. See https://github.com/ExpediaDotCom/graphql-kotlin/wiki/Fields#documenting-fields for more details.
Is there some additional functionality needed that current annotation doesn't provide?
from graphql-kotlin.
GraphQL supports Markdown schema documentation. Our technique is pretty basic - we maintain a directory with Markdown files. The documentation can be as rich as Markdown allows (we use paragraphs, links, tables etc). Within those files an h1 (# ...
) demarcates a beginning of a type documentation. h2 (## ...
) demarcates a beginning of a field documentation. The directory structure doesn't really matter so we can organize these files as we see fit. Several types can be documented in the same file. Our documentation team uses an external tool to author the files (mostly https://typora.io/).
Maintaining documentation by passing an argument to an annotation is disadvantageous because:
- it's very limiting. It isn't convenient to read/write anything more than pretty short string values. We don't consider that adequate documentation for our API.
- it's maintained as part of the code. While this may be perfectly fine for many cases we find it hinders collaboration with our documentation team.
- There can be many GraphQL API endpoints implemented using different stacks but we would like the documentation for all of them to be maintained coherently using the same documentation method.
We generate another GraphQL schema for another use case not using graphql-kotlin using the documentation technique I described above successfully and we would like to continue to document all our APIs in similar way.
We would happily contribute the above mentioned documentation technique although it's very simple. It only involves scanning a directory for Markdown files, parsing them using https://github.com/vsch/flexmark-java and providing a resolution method for types and fields.
from graphql-kotlin.
@liqweed I see why you would want this with your dynamic documentation.
We could add a method for every GraphQLType
implementation but would it make more sense if we added a hook at the the same location as didGenerateGraphQLType
? This is called right before we add the type to the schema but that is not helpful for you since we don't use the modified value if you were to change it in the hook.
If we added a new hook at the same location as didGenerateGraphQLType
, we can have you modify the type by passing it into a builder again and the returning it.
/**
* Called after using reflection to generate the graphql object type but before returning it to the schema.
* This allows for modifying the type info, like description or directives
*/
fun willAddGraphQLTypeToSchema(type: KType, generatedType: GraphQLType): GraphQLType = generatedType
Your hooks can check all the possible types
override fun willAddGraphQLTypeToSchema(type: KType, generatedType: GraphQLType): GraphQLType {
return when (generatedType) {
is GraphQLObjectType -> GraphQLObjectType.Builder(generatedType).description("My custom description + old one: ${generatedType.description}").build()
else -> generatedType
}
}
from graphql-kotlin.
To add description for fields I would also need the field's name at that point. The builders don't expose the added fields for inspection or manipulation.
If I understand correctly, according to your suggestion I should traverse all the information in the builder, including its fields, and create a copy based on that - right?
from graphql-kotlin.
Are there use cases for mutating hooks besides adding markdown docs, could it be used to implement custom directives? #88 (comment)
from graphql-kotlin.
@smyrick To make sure I follow your comment about modifying fields using this new hook, do you mean like so?
class DocumentationSchemaGeneratorHooks : SchemaGeneratorHooks {
override fun willAddGraphQLTypeToSchema(type: KType, generatedType: GraphQLType): GraphQLType {
return when(generatedType) {
is GraphQLObjectType -> {
val builder = GraphQLObjectType.Builder(generatedType)
builder.clearFields()
generatedType.fieldDefinitions.forEach {
builder.field(GraphQLFieldDefinition.Builder(it).description(resolveFieldDocumentation(generatedType.name, it.name)))
}
builder.description(resolveTypeDocumentation(generatedType.name)).build()
}
else -> generatedType
}
}
}
from graphql-kotlin.
@liqweed Yep that looks correct, I know it's a few lines to parse but with some helper functions you can reuse the code for all the types, not just object types.
If that doesn't work please feel free to create a new issue with this hook
from graphql-kotlin.
@smyrick Thanks, I think that would do.
Thank you for such a quick handling of the issue!
Looking forward to seeing this in an upcoming release.
from graphql-kotlin.
This mechanism works well for all GraphQLType
s except for GraphQLInterfaceType
s.
The following code:
override fun willAddGraphQLTypeToSchema(type: KType, generatedType: GraphQLType): GraphQLType {
return when (generatedType) {
is GraphQLInterfaceType -> GraphQLInterfaceType.newInterface(generatedType)
.description("My resolved description").build()
else -> generatedType
}
}
Produces the following error:
graphql.AssertException: All types within a GraphQL schema must have unique names. No two provided types may have the same name.
No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types).
You have redefined the type 'Result' from being a 'GraphQLInterfaceType' to a 'GraphQLInterfaceType'
at graphql.schema.GraphQLTypeCollectingVisitor.assertTypeUniqueness(GraphQLTypeCollectingVisitor.java:105)
at graphql.schema.GraphQLTypeCollectingVisitor.visitGraphQLInterfaceType(GraphQLTypeCollectingVisitor.java:58)
at graphql.schema.GraphQLInterfaceType.accept(GraphQLInterfaceType.java:152)
at graphql.schema.TypeTraverser$TraverserDelegateVisitor.enter(TypeTraverser.java:71)
at graphql.util.Traverser.traverse(Traverser.java:147)
at graphql.schema.TypeTraverser.doTraverse(TypeTraverser.java:58)
at graphql.schema.TypeTraverser.depthFirst(TypeTraverser.java:50)
at graphql.schema.TypeTraverser.depthFirst(TypeTraverser.java:38)
at graphql.schema.SchemaUtil.allTypes(SchemaUtil.java:42)
at graphql.schema.GraphQLSchema.<init>(GraphQLSchema.java:102)
at graphql.schema.GraphQLSchema.<init>(GraphQLSchema.java:37)
at graphql.schema.GraphQLSchema$Builder.build(GraphQLSchema.java:411)
at com.expedia.graphql.generator.SchemaGenerator.generate$graphql_kotlin_schema_generator(SchemaGenerator.kt:68)
at com.expedia.graphql.ToSchemaKt.toSchema(toSchema.kt:24)
at com.expedia.graphql.ToSchemaKt.toSchema$default(toSchema.kt:21)
from graphql-kotlin.
@liqweed These seems like a valid error, I have created a new issue which is open for anyone to work on #281
from graphql-kotlin.
Related Issues (20)
- Make `src/main/resources` configurable for GraphQL clients HOT 1
- Spring WebFlux: How to autowire a service/component in a CustomDirective behavior?
- ControllerAdvice and ModelAttribute
- [generator] support directives using input object args
- GraphQL Ktor plugin swallows context exceptions. HOT 3
- Ktor: Flow/Subscription websocket stops working (Ping Timeout)
- Why do I get this error when I start the application HOT 2
- No code generation occurs, no logs explaining why HOT 9
- feat: allow classes corresponding to SDL to be decoupled from implementation
- Unable to retrieve federated types with apollo federation v1 HOT 1
- Add plugin configuration option to allow generating test client files into testFixtures sources root
- @ShareableDirective causes schema generation error when applied to class used as both input and output
- FederatedSchemaValidator rejects nested union type field set HOT 1
- Union Annotations Do Not Play Well with @GraphQLDescription and @Deprecated
- FunctionDataFetcher: does not handle `Error` descendant `Throwables` in `runBlockingFunction` in conjunction with GraphQL Java `graphql/execution/ExecutionStrategy.java`
- 7.1.0 introduces Spring Boot Micrometer metrics errors HOT 4
- bug(federation): graphql-java v22 update breaks deprecation notices
- Spring Boot 3.3.0 breaks the code generator in version 7.xx HOT 3
- [maven plugin] Make serializer optional in client generation
- Support for persisted queries? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphql-kotlin.