Skip to content

Add module-specific OpenAPI documents - #5

Merged
PANiXiDA merged 6 commits into
mainfrom
feature/module-openapi-documents
Aug 2, 2026
Merged

Add module-specific OpenAPI documents#5
PANiXiDA merged 6 commits into
mainfrom
feature/module-openapi-documents

Conversation

@PANiXiDA

@PANiXiDA PANiXiDA commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

What changed

  • Added opt-in module-specific OpenAPI documents and Scalar document selection.
  • Changed module registration to accept presentation assemblies in code while reading each document Name and Title from HttpModules configuration keyed by the assembly simple name.
  • Kept HttpModule and HttpModuleRegistry internal under Modularity: the module is resolved endpoint metadata, while the registry validates and indexes it by assembly.
  • Simplified OpenAPI document registration with modules.Select(static module => module.Name).
  • Kept the existing combined /openapi/v1.json behavior when no module assemblies are registered.
  • Updated Asp.Versioning.Http and Asp.Versioning.OpenApi to 10.0.1, Microsoft.AspNetCore.OpenApi to 10.0.10, and both Scalar packages to 2.16.17.
  • Promoted the library version from 2.0-preview to stable 2.0 and updated the README package reference to 2.0.0.
  • Added validation and tests for missing configuration, null and duplicate assemblies, duplicate document names, endpoint metadata, document isolation, Scalar sources, and assembly mapping deduplication.

Why

Applications composed from multiple presentation modules need focused OpenAPI documents without coupling document grouping to API versions. Assemblies remain type-safe code references, while document identifiers and UI titles can now vary by environment without recompilation.

Usage

builder.Services.AddHttp(
    builder.Configuration,
    typeof(IdentityPresentationAssembly).Assembly,
    typeof(CompendiumPresentationAssembly).Assembly);
{
  "HttpModules": {
    "PANiXiDA.TacticalHeroes.Identity.Presentation": {
      "Name": "identity",
      "Title": "Identity API"
    },
    "PANiXiDA.TacticalHeroes.Compendium.Presentation": {
      "Name": "compendium",
      "Title": "Compendium API"
    }
  }
}

Each HttpModules key must equal Assembly.GetName().Name. Name and Title are required for every registered assembly.

Local verification

dotnet restore
dotnet format --verify-no-changes --no-restore
dotnet build --configuration Release --no-restore
dotnet test --configuration Release --no-build --no-restore
dotnet test tests/PANiXiDA.Core.Presentation.Http.UnitTests/PANiXiDA.Core.Presentation.Http.UnitTests.csproj --configuration Debug --no-restore -- --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml
dotnet pack --configuration Release --no-build --no-restore
dotnet package list --project PANiXiDA.Core.Presentation.Http.slnx --vulnerable --include-transitive --no-restore

Result: Release build succeeded with no warnings, all 70 tests passed, Cobertura coverage is 100% for lines (555/555) and branches (151/151), package creation succeeded, and no vulnerable or prerelease dependencies were reported.

Compatibility

  • Migrations: none.
  • Configuration changes: no configuration is required for the existing combined document; every assembly passed to the new overload requires a matching HttpModules section.
  • Public contracts: the unreleased HttpModule overload is replaced by AddHttp(IConfiguration, params Assembly[]); HttpModule is now internal.
  • Package versioning: the library moves from the 2.0-preview line to stable 2.0.
  • Breaking changes: none relative to the currently published package. Existing AddHttp(configuration) and combined v1 behavior remain unchanged.

@PANiXiDA
PANiXiDA marked this pull request as ready for review August 2, 2026 06:45
@PANiXiDA
PANiXiDA merged commit 21f21fb into main Aug 2, 2026
4 checks passed
@PANiXiDA
PANiXiDA deleted the feature/module-openapi-documents branch August 2, 2026 06:45

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d698e77a7b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

$"Configuration section '{moduleSection.Path}' is required.");
}

var name = GetRequiredValue(moduleSection, nameof(HttpModule.Name));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject document names that cannot form route segments

When a configured Name contains / (for example, sales/v1), it passes the whitespace-only validation and is registered as an OpenAPI document, but MapOpenApi exposes only the single-segment route /openapi/{documentName}.json. Consequently, /openapi/sales/v1.json cannot resolve that document, leaving both direct access and its Scalar source unusable; validate module names as safe route-segment values before registration.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants