Multiple OpenAPI Documents

Shows how to serve multiple OpenAPI documents (a default document plus a separate webhook document) from the same Kestrun server.

Full source

File: pwsh/tutorial/examples/10.18-OpenAPI-MultiDocs.ps1

<#
    Sample: OpenAPI Multi-Document
    Purpose: Demonstrate multiple OpenAPI documents (default + webhook) in a single server.
    File:    10.18-OpenAPI-MultiDocs.ps1
    Notes:   Shows multi-document OpenAPI configuration and routing for both standard paths and webhooks.
#>

param(
    [int]$Port = 5000,
    [IPAddress]$IPAddress = [IPAddress]::Loopback
)

# --- Logging / Server ---

New-KrLogger | Add-KrSinkConsole |
    Set-KrLoggerLevel -Value Debug |
    Register-KrLogger -Name 'console' -SetAsDefault

New-KrServer -Name 'OpenAPI Hello World'

Add-KrEndpoint -Port $Port -IPAddress $IPAddress
# =========================================================
#                 TOP-LEVEL OPENAPI
# =========================================================

Add-KrOpenApiInfo -Title 'Hello World API' `
    -Version '1.0.0' `
    -Description 'A simple OpenAPI 3.1 example with a single endpoint.'

Add-KrOpenApiInfo -Title 'Hello World API' `
    -Version '1.0.0' `
    -Description 'A simple OpenAPI 3.1 example with a single endpoint.' -DocId 'WebHookDoc'

Add-KrOpenApiContact -Email 'support@example.com'
# Add Server info
Add-KrOpenApiServer -Url "http://$($IPAddress):$Port" -Description 'Local Server'

# =========================================================
#                 ROUTES / OPERATIONS
# =========================================================

Enable-KrConfiguration

Add-KrApiDocumentationRoute -DocumentType Swagger
Add-KrApiDocumentationRoute -DocumentType Redoc

# Simple GET endpoint with a text response

<#
.SYNOPSIS
    Get greeting message (Webhook).
.DESCRIPTION
    Returns a simple greeting message (Webhook).
#>
function getGreetingWebHook {
    [OpenApiWebhook(HttpVerb = 'get' , Pattern = '/greeting' , DocumentId = 'WebHookDoc' )]
    param()
}

<#
.SYNOPSIS
    Get greeting message.
.DESCRIPTION
    Returns a simple greeting message.
#>
function getGreeting {
    [OpenApiPath(HttpVerb = 'get' , Pattern = '/greeting' )]
    param()
    Write-KrTextResponse -Text 'Hello, World!' -StatusCode 200
}
# =========================================================
#                OPENAPI DOC ROUTE / BUILD
# =========================================================
Add-KrOpenApiRoute
Add-KrOpenApiRoute -DocumentId 'WebHookDoc' # Default pattern '/openapi/{version}/openapi.{format}'

# =========================================================
#                      RUN SERVER
# =========================================================

Start-KrServer -CloseLogsOnExit

Step-by-step

  1. Logging: Configure a console logger and set the minimum level.
  2. Server: Create a server instance with New-KrServer and add a listening endpoint using Add-KrEndpoint.
  3. Default OpenAPI doc metadata: Set info.title, info.version, and description using Add-KrOpenApiInfo.
  4. Second OpenAPI doc metadata: Call Add-KrOpenApiInfo again with -DocId 'WebHookDoc' to create a separate document descriptor.
  5. Shared metadata: Add contact and server information using Add-KrOpenApiContact and Add-KrOpenApiServer.
  6. Configuration: Call Enable-KrConfiguration to commit staged configuration.
  7. Documentation UIs: Register Swagger and ReDoc viewers using Add-KrApiDocumentationRoute.
  8. Webhook operation: Define a webhook operation using the [OpenApiWebhook] attribute and set DocumentId = 'WebHookDoc' so it is only emitted into the webhook document.
  9. Regular path operation: Define a normal request/response operation using [OpenApiPath] and return a response with Write-KrTextResponse.
  10. Expose OpenAPI routes:
    • Call Add-KrOpenApiRoute to expose the default document at /openapi/{version}/openapi.{format}.
    • Call Add-KrOpenApiRoute again with -DocumentId 'WebHookDoc' to expose the second document. When a non-default document id is used with the default pattern, Kestrun serves it at /openapi/{documentId}/{version}/openapi.{format}.
  11. Run: Start the server using Start-KrServer.

Try it

Run the example from the repository root:

Import-Module .\src\PowerShell\Kestrun\Kestrun.psd1 -Force
.\docs\_includes\examples\pwsh\10.18-OpenAPI-MultiDocs.ps1 -Port 5000

Fetch both OpenAPI documents (JSON) using curl:

# Default document
curl -i http://127.0.0.1:5000/openapi/v3.1/openapi.json

# Webhook-only document (DocId = 'WebHookDoc')
curl -i http://127.0.0.1:5000/openapi/WebHookDoc/v3.1/openapi.json

Browse the documentation UIs:

  • Swagger UI: http://127.0.0.1:5000/swagger
  • ReDoc: http://127.0.0.1:5000/redoc

Troubleshooting

  • 404 from OpenAPI endpoints: Ensure you include an OpenAPI spec version like v3.1 in the URL (/openapi/v3.1/openapi.json).
  • Missing webhook operations in the default doc: Confirm your webhook function uses DocumentId = 'WebHookDoc' so it is scoped to the webhook document.
  • Multiple docs but only one route: You need one Add-KrOpenApiRoute call per document you want to expose.

References


Previous / Next

Previous: Redocly Museum API Next: Product Search with HTTP QUERY (OpenAPI 3.2)