-
Notifications
You must be signed in to change notification settings - Fork 344
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
Support hooks to add custom documentation to objects, fields, arguments and enum values #231
Comments
You can add custom documentation using Is there some additional functionality needed that current annotation doesn't provide? |
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 ( Maintaining documentation by passing an argument to an annotation is disadvantageous because:
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. |
@liqweed I see why you would want this with your dynamic documentation. We could add a method for every If we added a new hook at the same location as /**
* 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
}
} |
Fixes ExpediaGroup#231 Adds a new hook that can be used to modify all the GraphQLTypes that get generated from reflection. This allows for runtime documentation or any other changes that may want to be made to types after they are fully generated
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. |
Are there use cases for mutating hooks besides adding markdown docs, could it be used to implement custom directives? #88 (comment) |
@liqweed You can access the name of the @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 |
Fixes #231 Adds a new hook that can be used to modify all the GraphQLTypes that get generated from reflection. This allows for runtime documentation or any other changes that may want to be made to types after they are fully generated
@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
}
}
} |
@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 |
@smyrick Thanks, I think that would do. Thank you for such a quick handling of the issue! |
This mechanism works well for all The following code:
Produces the following error:
|
Fixes ExpediaGroup#231 Adds a new hook that can be used to modify all the GraphQLTypes that get generated from reflection. This allows for runtime documentation or any other changes that may want to be made to types after they are fully generated
We came up with a documentation technique that works well for us (syncing both development teams and our product documentation team). We're trying to resolve the relevant Markdown documentation for each object, field, argument and enum value.
SchemaGeneratorHooks
is an awesome general purpose vehicle for intercepting schema generation. I think it can be very helpful in this case, but it would have to be extended to include hook methods that would allow me to augment builder objects just before callingbuild()
. That way I can call the builders'description
method and add my own documentation. Specifically I'm asking for the inclusion of the following hooks:I added the names of the objects/fields/arguments/enums to the hooks' contexts since it's difficult to extract that information from the builders directly.
What do you think?
Thanks a lot for a fantastic library!
The text was updated successfully, but these errors were encountered: