Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 26 additions & 15 deletions website/src/components/articles/doc-article-navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ interface DocArticleNavigationProduct {
items?: Array<{
path?: string | null;
title?: string | null;
items?: Array<{
path?: string | null;
title?: string | null;
} | null> | null;
} | null> | null;
} | null> | null;
} | null> | null;
Expand Down Expand Up @@ -110,21 +114,28 @@ export const DocArticleNavigation: FC<DocArticleNavigationProps> = ({
const hasVersions =
!activeProduct?.versions || activeProduct.versions.length > 1;

const subItems: Item[] =
activeVersion?.items
?.filter((item) => !!item)
.map<Item>((item) => ({
path: item!.path!,
title: item!.title!,
items: item!.items
? item?.items
.filter((item) => !!item)
.map<Item>((item) => ({
path: item!.path!,
title: item!.title!,
}))
: undefined,
})) ?? [];
function mapItems(
raw:
| Array<{
path?: string | null;
title?: string | null;
items?: any;
} | null>
| null
| undefined
): Item[] {
return (
raw
?.filter((item) => !!item)
.map<Item>((item) => ({
path: item!.path!,
title: item!.title!,
items: item!.items ? mapItems(item!.items) : undefined,
})) ?? []
);
}

const subItems: Item[] = mapItems(activeVersion?.items);

const basePath = `/docs/${activeProduct!.path!}${
!!activeVersion?.path?.length ? "/" + activeVersion.path : ""
Expand Down
170 changes: 53 additions & 117 deletions website/src/docs/docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -575,24 +575,34 @@
]
},
{
"path": "fetching-data",
"title": "Resolvers and Data",
"path": "resolvers",
"title": "Resolvers",
"items": [
{
"path": "index",
"title": "Overview"
},
{
"path": "resolvers",
"title": "Resolvers"
"title": "Introduction"
},
{
"path": "dependency-injection",
"title": "Dependency Injection"
},
{
"path": "dataloader",
"title": "DataLoader"
"path": "errors",
"title": "Errors"
},
{
"path": "field-middleware",
"title": "Field Middleware"
}
]
},
{
"path": "fetching-data",
"title": "Fetching Data",
"items": [
{
"path": "index",
"title": "Overview"
},
{
"path": "pagination",
Expand All @@ -610,101 +620,45 @@
"path": "projections",
"title": "Projections"
},
{
"path": "fetching-from-databases",
"title": "Fetching from Databases"
},
{
"path": "fetching-from-rest",
"title": "Fetching from REST"
},
{
"path": "entity-framework",
"title": "Entity Framework"
},
{
"path": "mongodb",
"title": "MongoDB"
},
{
"path": "spatial-data",
"title": "Spatial Data"
},
{
"path": "marten",
"title": "Marten"
},
{
"path": "errors",
"title": "Error Codes"
},
{
"path": "extending-filtering",
"title": "Extending Filtering"
},
{
"path": "executable",
"title": "Executable"
}
]
},
{
"path": "guides",
"title": "Guides",
"items": [
{
"path": "public-api",
"title": "Building a Public API"
},
{
"path": "private-api",
"title": "Building a Private API"
},
{
"path": "error-handling",
"title": "Error Handling"
},
{
"path": "schema-evolution",
"title": "Schema Evolution"
},
{
"path": "testing",
"title": "Testing"
},
{
"path": "performance",
"title": "Performance"
},
{
"path": "dynamic-schemas",
"title": "Dynamic Schemas"
},
{
"path": "mcp-adapter",
"title": "MCP Adapter"
},
{
"path": "openapi-adapter",
"title": "OpenAPI Adapter"
},
{
"path": "federation",
"title": "Federation"
}
]
},
{
"path": "execution-engine",
"title": "Execution Engine",
"items": [
{
"path": "index",
"title": "Overview"
},
{
"path": "field-middleware",
"title": "Field Middleware"
"path": "batching",
"title": "Batching",
"items": [
{
"path": "dataloader",
"title": "DataLoader"
},
{
"path": "batch-resolver",
"title": "Batch Resolvers"
}
]
},
{
"path": "integrations",
"title": "Integrations",
"items": [
{
"path": "entity-framework",
"title": "Entity Framework"
},
{
"path": "mongodb",
"title": "MongoDB"
},
{
"path": "marten",
"title": "Marten"
},
{
"path": "extending-filtering",
"title": "Extending Filtering"
}
]
}
]
},
Expand Down Expand Up @@ -810,24 +764,6 @@
}
]
},
{
"path": "api-reference",
"title": "API Reference",
"items": [
{
"path": "custom-attributes",
"title": "Attributes"
},
{
"path": "language",
"title": "Language"
},
{
"path": "visitors",
"title": "Visitors"
}
]
},
{
"path": "migrating",
"title": "Migrating",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ public static Product? GetProduct(
=> db.Products.Find(id);
```

In v16, you can also use the generic form `[ID<Product>]` which infers the type name automatically.
You can also use the generic form `[ID<Product>]` which infers the type name automatically.

# Complex Arguments

Expand Down Expand Up @@ -219,4 +219,4 @@ type Query {
- **Need structured input?** See [Input Object Types](/docs/hotchocolate/v16/defining-a-schema/input-object-types).
- **Need to understand nullability?** See [Non-Null](/docs/hotchocolate/v16/defining-a-schema/non-null).
- **Need global IDs?** See [Relay](/docs/hotchocolate/v16/defining-a-schema/relay).
- **Need to set up resolvers?** See [Resolvers](/docs/hotchocolate/v16/fetching-data/resolvers).
- **Need to set up resolvers?** See [Resolvers](/docs/hotchocolate/v16/resolvers/resolvers).
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ In code-first, the `Description()` method takes precedence over all other forms

# Using XML Documentation Comments

Hot Chocolate can generate descriptions from standard C# XML documentation comments. This lets you maintain a single source of documentation for both your C# code and GraphQL schema.
Hot Chocolate generates descriptions from standard C# XML documentation comments. The source generator extracts them at build time, so your C# code is the single source of documentation for both your code and GraphQL schema.

```csharp
/// <summary>
Expand Down Expand Up @@ -128,9 +128,59 @@ public static partial class UserQueries
}
```

## Enabling XML Documentation
## Source Generator (Default)

To make XML docs available at runtime, enable `GenerateDocumentationFile` in your `.csproj`:
Hot Chocolate's source generator extracts XML documentation comments directly from the source code during compilation. This is the default behavior, no additional project configuration is required.

The source generator reads `<summary>`, `<param>`, `<returns>`, and `<exception>` tags and embeds the extracted text into the generated type configuration. Because this happens at build time, you do not need to ship XML documentation files with your application.

### Supported Tags

| Tag | Usage |
| ----------------------------------- | -------------------------------------------------------------------- |
| `<summary>` | Sets the description of the type, field, or enum value. |
| `<param name="...">` | Sets the description of a field argument. |
| `<returns>` | Appended to the field description under a **Returns** heading. |
| `<exception cref="..." code="...">` | Appended under an **Errors** heading. Requires the `code` attribute. |
| `<inheritdoc />` | Resolves documentation from a base class or interface. |
| `<inheritdoc cref="..." />` | Resolves documentation from a specific member. |

### Example with Returns and Errors

```csharp
[QueryType]
public static partial class UserQueries
{
/// <summary>
/// Finds a user by their unique username.
/// </summary>
/// <param name="username">The username to search for.</param>
/// <returns>The matching user, or null if not found.</returns>
/// <exception cref="Exception" code="NOT_AUTHORIZED">
/// The caller does not have permission to search users.
/// </exception>
public static User? GetUser(string username, UserService users)
=> users.FindByName(username);
}
```

This produces a field description that includes the summary, a **Returns** section, and an **Errors** section.

### Disabling Source Generator Documentation

To prevent the source generator from extracting XML documentation, add the `Module` attribute with the `DisableXmlDocumentation` option:

```csharp
using HotChocolate;

[assembly: Module("MyModule", ModuleOptions.Default | ModuleOptions.DisableXmlDocumentation)]
```

When `DisableXmlDocumentation` is set, `[GraphQLDescription]` attributes continue to work. Only the automatic extraction of XML comments is suppressed.

## Runtime XML Documentation

If you are not using the source generator or need XML documentation from referenced assemblies outside the source generator's scope, Hot Chocolate can read XML documentation files at runtime. Enable `GenerateDocumentationFile` in your `.csproj`:

```xml
<PropertyGroup>
Expand All @@ -141,9 +191,9 @@ To make XML docs available at runtime, enable `GenerateDocumentationFile` in you

The `<NoWarn>` element is optional. It suppresses compiler warnings for types without documentation comments.

## Disabling XML Documentation
### Disabling Runtime XML Documentation

If you do not want XML comments to appear in the schema:
If you do not want runtime XML comments to appear in the schema:

```csharp
builder
Expand All @@ -161,7 +211,7 @@ When both `[GraphQLDescription]` and XML documentation are present, they follow

# Custom Naming Conventions

If you use a custom naming convention and XML documentation, pass an `XmlDocumentationProvider` to the convention so descriptions are preserved:
If you use a custom naming convention and runtime XML documentation, pass an `XmlDocumentationProvider` to the convention so descriptions are preserved. This does not apply when using the source generator, which handles documentation extraction at build time.

```csharp
public class CustomNamingConventions : DefaultNamingConventions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,6 @@ builder

# Next Steps

- **Need to extend existing types?** See [Extending Types](/docs/hotchocolate/v16/defining-a-schema/extending-types).
- **Need to extend existing types?** See [Extending Types](/docs/hotchocolate/v16/defining-a-schema/object-types).
- **Need to define types with the descriptor API?** See [Object Types](/docs/hotchocolate/v16/defining-a-schema/object-types).
- **Need to understand type modules in depth?** Explore the `ITypeModule` interface in the Hot Chocolate source code under `src/HotChocolate/Core/src/Types/`.
4 changes: 2 additions & 2 deletions website/src/docs/hotchocolate/v16/defining-a-schema/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ Organize your schema for maintainability and support advanced modeling scenarios

| Topic | Use it for | Learn more |
| --------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------ |
| Type extensions | Split large object or root type definitions across classes. Extensions are merged into the final schema. | [Extending Types](./extending-types) |
| Type extensions | Split large object or root type definitions across classes. Extensions are merged into the final schema. | [Object Types](./object-types) |
| Relay helpers | Use stable IDs, global object identification, `node`, `nodes`, `[ID]`, `[Node]`, and `[NodeResolver]`. | [Relay](./relay) |
| Dynamic schemas | Generate types from CMS, multi-tenant, or configuration-driven metadata with `ITypeModule`. | [Dynamic Schemas](./dynamic-schemas) |

Expand All @@ -199,4 +199,4 @@ Use type extensions for static modularity. Choose dynamic schemas only when the
- Learn how returned shapes are inferred and configured in [Object Types](./object-types).
- Add field inputs with [Arguments](./arguments) and [Input Object Types](./input-object-types).
- Strengthen the contract with [Lists and Non-Null](./lists).
- Move to runtime behavior with [Resolvers](../fetching-data/resolvers) and [DataLoader](../fetching-data/dataloader) after the schema shape is clear.
- Move to runtime behavior with [Resolvers](../resolvers/resolvers) and [DataLoader](../fetching-data/batching/dataloader) after the schema shape is clear.
Original file line number Diff line number Diff line change
Expand Up @@ -366,5 +366,5 @@ Object types can override an inherited resolver by defining their own resolver f

- **Need types without shared fields?** See [Unions](/docs/hotchocolate/v16/defining-a-schema/unions).
- **Need to define output types?** See [Object Types](/docs/hotchocolate/v16/defining-a-schema/object-types).
- **Need to extend an existing type?** See [Extending Types](/docs/hotchocolate/v16/defining-a-schema/extending-types).
- **Need to extend an existing type?** See [Extending Types](/docs/hotchocolate/v16/defining-a-schema/object-types).
- **Need to document interface fields?** See [Documentation](/docs/hotchocolate/v16/defining-a-schema/documentation).
Loading