Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<PackageVersion Include="Jint" Version="4.16.3" />
<PackageVersion Include="JsonSchema.Net" Version="[8.0.5]" />
<PackageVersion Include="Markdig" Version="1.4.0" />
<PackageVersion Include="Microsoft.OpenApi" Version="3.10.2" />
<PackageVersion Include="Microsoft.OpenApi.YamlReader" Version="3.10.2" />
<PackageVersion Include="Microsoft.Playwright" Version="1.62.0" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="OneOf" Version="3.0.271" />
Expand Down
123 changes: 123 additions & 0 deletions docs/docs/openapi-3-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
openapi: 3.0.3
info:
title: Catalog API (OpenAPI 3.0)
version: '1.0'
description: |
This page is generated directly from an **OpenAPI 3.0.3** document.
Explore path and query parameters, a JSON request body, response examples,
and reusable schemas below. The server address is illustrative.

See the [REST API guide](rest-api-docs.md#openapi-3-documents) to document your own API.
servers:
- url: https://api.example.com/v1
description: Example catalog server.
tags:
- name: Products
description: Read and create products in a catalog.
paths:
/products/{id}:
get:
operationId: getProduct
tags: [Products]
summary: Get a product
description: Returns a product by its identifier.
parameters:
- name: id
in: path
required: true
description: The product identifier.
schema:
type: string
- name: includeArchived
in: query
description: Include products that are no longer available.
schema:
type: boolean
default: false
responses:
'200':
description: The requested product.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
example:
id: notebook
name: Paper notebook
price: 12.5
status: available
'404':
description: No product has this identifier.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
example:
code: product_not_found
message: The product does not exist.
/products:
post:
operationId: createProduct
tags: [Products]
summary: Create a product
description: Creates a product from a JSON request body.
requestBody:
required: true
description: The name and price of the new product.
content:
application/json:
schema:
$ref: '#/components/schemas/NewProduct'
example:
name: Paper notebook
price: 12.5
responses:
'201':
description: The product was created.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
example:
id: notebook
name: Paper notebook
price: 12.5
status: available
components:
schemas:
NewProduct:
type: object
required: [name, price]
properties:
name:
type: string
description: The **display name** of the product.
minLength: 1
price:
type: number
format: double
description: Unit price in the catalog currency.
minimum: 0
Product:
allOf:
- $ref: '#/components/schemas/NewProduct'
- type: object
required: [id, status]
properties:
id:
type: string
description: The product identifier.
status:
type: string
description: Current availability.
enum: [available, archived]
Error:
type: object
required: [code, message]
properties:
code:
type: string
description: A machine-readable error code.
message:
type: string
description: A description of the error.
63 changes: 63 additions & 0 deletions docs/docs/openapi-32-example.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
openapi: 3.2.0
info:
title: Event Stream API
version: '1.0'
description: |
This OpenAPI 3.2 example demonstrates **streaming responses**, the `QUERY`
method and an additional HTTP method. The Event schema includes typed
constants, a null default and boolean schemas.
servers:
- url: https://api.example.com/v1
paths:
/events:
query:
operationId: queryEvents
summary: Query the event stream
description: Each line in the response is one Event, described under **Stream item**.
responses:
'200':
description: A stream of matching events.
content:
application/jsonl:
itemSchema:
$ref: '#/components/schemas/Event'
examples:
structured:
dataValue:
version: 1
active: true
context: {source: catalog}
codes: [1, 2]
cursor: null
wire:
serializedValue: |
{"version":1,"active":true,"context":{"source":"catalog"},"codes":[1,2],"cursor":null}
additionalOperations:
COPY:
operationId: copyEvents
summary: Copy the current events
responses:
'204':
description: The events were copied.
components:
schemas:
Event:
type: object
properties:
version:
type: integer
const: 1
description: The event format version, preserved as a number.
active:
type: boolean
const: true
context:
const: {source: catalog}
codes:
const: [1, 2]
cursor:
type: [string, 'null']
default:
description: An omitted YAML default value means null.
metadata: true
forbidden: false
94 changes: 94 additions & 0 deletions docs/docs/openapi-unsupported-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# OpenAPI features not yet supported

This page describes the unsupported features and known fidelity issues in the
[OpenAPI 3 REST documentation reader](rest-api-docs.md#openapi-3-documents),
which uses `Microsoft.OpenApi` and `Microsoft.OpenApi.YamlReader` **3.10.2**.
Swagger 2.0 JSON continues to use its existing reader and is not affected by these
OpenAPI 3 limitations.

OpenAPI 3.0, 3.1 and 3.2 JSON/YAML documents are accepted, but this is not full
OpenAPI or JSON Schema conformance. Parsing a document successfully does not mean
every feature is rendered. The list below describes known boundaries, not a
commitment to a particular release or an exhaustive conformance matrix.

## Features that produce an error

These cases produce an input error rather than falling back to the Swagger reader.
The affected document is not generated.

| Feature | Current behavior | Reason or alternative |
| --- | --- | --- |
| Cross-file and network `$ref` targets | `UnsupportedExternalReference` | Put components in the current document and use references such as `#/components/schemas/Pet`. |
| Future specification versions | Version error | Only OpenAPI 3.0, 3.1 and 3.2 are enabled. |
| Dynamic schema references (`$dynamicRef`) | `UnsupportedOpenApiSchema` | Dynamic scope is not implemented. Ordinary `$ref`, including recursive references, is supported. |
| Certain OpenAPI 3.0 primitive compositions | `UnsupportedOpenApiComposition` | The pinned SDK can lose exclusive alternatives or branch examples. See [primitive compositions](#primitive-compositions). |

### Primitive compositions

In some OpenAPI 3.0 cases, the pinned SDK combines primitive alternatives into a
type union. This is not always equivalent to `oneOf`, which requires exactly one
matching branch:

```yaml
oneOf:
- type: integer
- type: number
```

The value `3` matches both branches and must fail this `oneOf`. Displaying it as
`integer | number` would lose that restriction. Type-only `oneOf` branches with
duplicate types have a similar problem. The SDK can also discard examples attached
to primitive branches during this conversion.

The reader rejects these known lossy OpenAPI 3.0 forms. Disjoint type-only
alternatives, such as `string` and `integer`, can become equivalent unions.
Constrained alternatives and OpenAPI 3.1/3.2 compositions are not blanket-rejected.

## Features without dedicated documentation UI

These features produce a warning when encountered. Supported parts of the document
can still be generated; treating warnings as errors can make the warning a build
failure. Their presence is not an indication that the following details are rendered.

| Feature | Information not currently rendered |
| --- | --- |
| Callbacks | Callback operations, parameters and payloads associated with an API operation. |
| Webhooks | Top-level webhook operations and their requests/responses. |
| Security schemes and requirements | API key, HTTP/Bearer, OAuth2 and OpenID Connect configuration, operation requirements and scopes. |
| Media-type encoding | `encoding`, `itemEncoding` and `prefixEncoding` details. |
| Tag summary, hierarchy and kind | Tags retain flat grouping; `summary`, `parent` and `kind` have no dedicated UI. |
| Response Link Objects | Relationships to subsequent operations and mappings from response values to their parameters. |

Response Link Objects are not ordinary Markdown links or Docfx cross-references;
those continue to work. Missing security documentation does not disable or change
authentication in the API itself.

## Supported schema values and OpenAPI 3.2 features

Typed `const` values, explicit and implicit YAML null defaults, and boolean schemas
are supported. Boolean schemas work in components, properties and composition arrays
as well as inline. Docfx preserves these values around known SDK reader limitations.
Values inside examples and extension data remain literal data.

OpenAPI 3.2 support includes `QUERY`, additional HTTP methods, reusable media types,
streaming `itemSchema`, and examples using `dataValue` or `serializedValue`.
See the [OpenAPI 3.2 example](openapi-32-example.yml) for generated output.

## SDK implementation notes

The following links identify the fixed SDK version behind the known behavior:

- [`JsonNodeHelper.CreateMap/CreateList`](https://github.com/microsoft/OpenAPI.NET/blob/v3.10.2/src/Microsoft.OpenApi/Reader/JsonNodeHelper.cs)
only pass object nodes to schema readers in map/list positions. Docfx normalizes
boolean schemas to equivalent objects before parsing.
- The [OpenAPI 3.0 schema reader](https://github.com/microsoft/OpenAPI.NET/blob/v3.10.2/src/Microsoft.OpenApi/Reader/V3/OpenApiSchemaDeserializer.cs)
performs the primitive-alternative folding described above.
- The [OpenAPI 3.1 schema reader](https://github.com/microsoft/OpenAPI.NET/blob/v3.10.2/src/Microsoft.OpenApi/Reader/V31/OpenApiSchemaDeserializer.cs)
reads `const` through `GetScalarValue` and models it as a string. Docfx retains
each original JSON value separately during SDK parsing and reference resolution,
then restores it during model conversion.
- The automatic [`OpenApiWorkspaceLoader`](https://github.com/microsoft/OpenAPI.NET/blob/v3.10.2/src/Microsoft.OpenApi/Reader/Services/OpenApiWorkspaceLoader.cs)
reuses the entry format and loads recursively before joining workspaces. Docfx
instead loads complete local documents once, detects each format, and registers
them with SDK workspaces before resolving references. It does not add a separate
JSON Pointer or schema resolver.
64 changes: 63 additions & 1 deletion docs/docs/rest-api-docs.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# REST API docs

Docfx generates REST API documentation from [Swagger 2.0](http://swagger.io/specification/) files.
Docfx generates REST API documentation from Swagger 2.0 JSON and OpenAPI 3.0, 3.1 and 3.2
JSON or YAML files, with documented feature limitations.
OpenAPI documents are read using [OpenAPI.NET](https://github.com/microsoft/OpenAPI.NET).
Swagger 2.0 continues to use the existing compatibility reader.

To add REST API docs, include the swagger JSON file to the `build` config in `docfx.json`:

Expand All @@ -16,6 +19,65 @@ To add REST API docs, include the swagger JSON file to the `build` config in `do

Each swagger file produces one output HTML file.

## OpenAPI 3 documents

See the [OpenAPI 3.0 example](openapi-3-example.yml) for a generated API page with
parameters, a request body, response examples and reusable schemas.
The [OpenAPI 3.2 example](openapi-32-example.yml) demonstrates streaming responses,
additional HTTP methods, typed constants, null defaults and boolean schemas.

Include the entry documents in `build.content`, for example:

```json
{
"build": {
"content": [{
"files": ["api/service.yaml", "api/other.json"]
}]
}
}
```

Both `.yaml` and `.yml` are supported. References must target the current document,
for example `#/components/schemas/Pet`. Cross-file and network references are not supported.
An invalid document or unresolved reference produces an input error, not a fallback
to the Swagger reader. OpenAPI 3.0, 3.1 and 3.2 are supported.

Operations reuse the existing Markdown, overwrite, cross-reference, tag and
operation splitting pipeline. Parameters, request bodies and response content
include their media types, schemas and examples. Example payloads are literal data,
not Markdown or documents whose `$ref` properties should be resolved.

Operation servers override path servers, which override document servers. Server
variables use their declared defaults; an omitted server defaults to `/`.
The root UID follows the existing authority/base-path/title/version convention
using the first document server. Operation UIDs append the operation ID. If an
operation has no ID, Docfx generates a stable, filename-safe ID from its HTTP method
and path. Explicit IDs must be unique. Tags used by operations need not be declared
at document level.

Schema documentation preserves alternatives and intersections rather than merging
`allOf`/`anyOf`/`oneOf` properties into a single object. OpenAPI 3.1/3.2 boolean schemas,
type unions and recursive references are displayed without expanding cycles. Schema
reference siblings are shown as an intersection with the target, not an override.
The SDK can normalize disjoint primitive alternatives into equivalent type unions.
This is documentation generation, not full JSON Schema validation or full OpenAPI
conformance. Callbacks, webhooks, security configuration and response links do not
have dedicated rendered UI. The original input remains available in the raw model.

OpenAPI 3.1/3.2 `const` values retain their JSON types, including numbers, booleans,
objects, arrays and null. Explicit and empty YAML null defaults are supported.
Boolean schemas work inline, in components and properties, and in composition arrays:
`true` accepts any value, while `false` accepts no value.

OpenAPI 3.2 `QUERY` and additional HTTP methods are rendered as operations. Streaming
media types display `itemSchema` under **Stream item**. Examples support structured
`dataValue` and literal `serializedValue`, as well as `value` and `externalValue`.

### Known OpenAPI.NET 3.10.2 limitations

See [OpenAPI features not yet supported](openapi-unsupported-features.md) for the
current input errors, features without dedicated UI, examples and SDK source references.

## Organize REST APIs using Tags

Expand Down
5 changes: 5 additions & 0 deletions docs/docs/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
- href: dotnet-api-docs.md
- href: sdk-compatibility.md
- href: rest-api-docs.md
- name: OpenAPI 3.0 example
href: openapi-3-example.yml
- name: OpenAPI 3.2 example
href: openapi-32-example.yml
- href: openapi-unsupported-features.md
- href: links-and-cross-references.md
- href: pdf.md

Expand Down
Loading