Hotchocolate: Generate schema descriptions from XML docstrings

Created on 5 May 2019  路  14Comments  路  Source: ChilliCream/hotchocolate

Is your feature request related to a problem? Please describe.
Currently the only way to provide descriptions to the GraphQL schema built using Hot Chocolate is through fluent APIs such as overriding the ObjectType<T>.Configure(IObjectTypeDescriptor<T>) method.

Describe the solution you'd like
I would like the XML docstrings that are part of my codebase to automatically generate descriptions in the generated GraphQL API. This will reduce the amount of effort required to properly document both my API and the C# code I write. As an example, given the following C# code

/// <summary>
/// Represents a character in the game.
/// </summary>
public class Character
{
    /// <summary>
    /// The name of the character.
    /// </summary>
    public string Name { get; set; }
}

then querying the API's for the Character type would present the following.

// GraphQL query
query {
  __type(name: "Character") {
    name,
    description,
    fields {
      name,
      description
    }
  }
}

// Response
{
  "data": {
    "__type": {
      "name": "Character",
      "description": "Represents a character in the game."
      "fields": [
        {
          "name": "name",
          "description": "The name of the character."
        }
      ]
    }
  }
}

The XML docstrings could serve as the default description for any types or queries, then be overridden by the fluent APIs.

Describe alternatives you've considered

  • The primary method of accomplishing this is to write duplicate documentation between XML docstrings and and the fluent APIs, leaving the possibility for inaccurate or mismatching documentation.
  • I was able to build some extension methods that use NJsonSchema to pull in property, class, and method XML doc summaries. Although it's possible to build the functionalities independently, it would be nice for this type of functionality to be supported out of the box.

    • One barrier I've encountered is adding descriptions for arguments to methods. If I only include a description then a HotChocolate.SchemaException is thrown due to a null value for the typeReference parameter. This can be overcome by manually including some kind of type mapping. I'm still exploring Hot Chocolate, so perhaps there is already a service/tool that can handle mapping default type mappings to IInputTypes?

Additional context
Other open source projects use XML documentation to generate API documentation for Swagger documents. Example projects include NSwag and Swashbuckle.

馃帀 enhancement

All 14 comments

After doing some digging through the NSwag source code, it looks like the functionality to read XML documentation for a given property/method/Type is part of the NJsonSchema library through theXmlDocumentExtensions. It seems like it would be possible to include NJsonSchema (even as a private asset in the library) and use the XML documentation as a default description, if present.

Hi @willwolfram18,

this is a good idea which I also considered. Do you want to help us with this one?

With version 9 the schema creation process is much easier extendable and I can walk you through it.

@michaelstaib I'd be happy to help with this! I've got a PoC on a branch in my fork but I'm not sure if where I put the docstring code is the best place. If you have a recommendation on where the best place to put the implementation is, I'd be more than happy to adjust my WIP!

  • [ ] Add Chapter Documentation

For the documentation chapter, it doesn't look like there are any docs in this repository. However I do see there is a ChilliCream/hotchocolate-docs repo. I'm guessing I will need to create the docs in that repo, yes?

@michaelstaib just wanted to follow up and see what you needed from me, if anything, to help get this issue closed and finish the PR. I think I have some time to take a swing at making an IDocumentationConventions interface to serve as the abstraction you mentioned in the PR.

For the documentation chapter, it doesn't look like there are any docs in this repository. However I do see there is a ChilliCream/hotchocolate-docs repo. I'm guessing I will need to create the docs in that repo, yes?

Yes we separated the docs so that we can update these more easily.

@michaelstaib just wanted to follow up and see what you needed from me, if anything, to help get this issue closed and finish the PR. I think I have some time to take a swing at making an IDocumentationConventions interface to serve as the abstraction you mentioned in the PR.

I am still trying to work out how we handle this. We will want to have the cache for the files but it should be gone after the schema is created. I am still not sure how we can get this done nicely.

At the moment each type requests the services. That means the services has to be a singleton in order to have a meaningful cache there. But that would leave us with the same problem.

I also think that fetching the files is something that should be separate from interpreting the xml structure.

Maybe for version 9 we should keep it simple and refactor this further after the release. Let me sleep on this one, I will have a better Idea about it tomorrow.

OK, I have split the file load log form the xml interpretation. We now have a IDocumentationProvider that now can also be implemented differently. People would need to register this as a service if they wanted a different implementation to be registered with the SchemaBuilder.

Per default we will use the XmlDocumentationProvider but if somebody wants to opt-out you can do so now.

Schema schema = SchemaBuilder.New()
    .AddQueryType<QueryWithDocumentation>()
    .ModifyOptions(options => options.UseXmlDocumentation = false)
    .Create();

The descriptor context is now created by the SchemaBuilder instead of the types. This allows us to get rid of the XmlDocumentationProvider instance, since we have now one method that creates the instance. This way the instance is collected by the GC after it was used. This feels much better then having a static cache forever that we in many cases just use once.

I am still not happy with the regex usage and the trims and stuff. I think I will revisit this and rewrite it using span like we do in the parser. Also I have extracted a lot of constants now, but there is still more to do here. I will merge the PR once it is green.

Also missing at the moment is enum xml documentation support. I will open an issue for that. #752

@willwolfram18 have you joined out slack channel?

I have created a documentation task so that we do not forget about it #753

This one is not included in preview.34

Was this page helpful?
0 / 5 - 0 ratings

Related issues

louisjrdev picture louisjrdev  路  3Comments

benmccallum picture benmccallum  路  5Comments

nigel-sampson picture nigel-sampson  路  5Comments

lTimeless picture lTimeless  路  5Comments

sascha-andres picture sascha-andres  路  4Comments