Skip to content

[API Explorer] Landing page setup#3120

Merged
lcawl merged 3 commits intomainfrom
api-landing-1
Apr 16, 2026
Merged

[API Explorer] Landing page setup#3120
lcawl merged 3 commits intomainfrom
api-landing-1

Conversation

@lcawl
Copy link
Copy Markdown
Contributor

@lcawl lcawl commented Apr 16, 2026

Summary

This PR provides the solid configuration foundation needed for subsequent PRs that implement support for custom API landing pages in the API Explorer.
The custom landing pages can optionally include sections such as https://www.elastic.co/docs/api/doc/kibana/topic/topic-kibana-spaces so that they don't have to be inserted in the OpenAPI document via overlays.

New YAML Syntax Support:

# Old format (still works)
api:
  elasticsearch: "elasticsearch-openapi.json"

# New format will support this format in subsequent PRs:
api:
  elasticsearch:
    spec: "elasticsearch-openapi.json"
    template: "elasticsearch-api-overview.md"

Implementation Details

Files Created/Modified:

  1. src/Elastic.Documentation.Configuration/Toc/ApiConfiguration.cs

    • New configuration model with template, spec, specs fields
    • Validation logic and helper methods
    • ResolvedApiConfiguration for validated file references
  2. src/Elastic.Documentation.Configuration/Toc/ApiConfigurationConverter.cs

    • YAML converter providing backward compatibility
    • Handles both old string format and new object format
    • Manual YAML parsing to avoid infinite recursion
  3. src/Elastic.Documentation.Configuration/Toc/DocumentationSetFile.cs

    • Updated api field from Dictionary<string, string> to Dictionary<string, ApiConfiguration>
  4. src/Elastic.Documentation.Configuration/ConfigurationFileProvider.cs

    • Registered ApiConfigurationConverter in the static deserializer
  5. src/Elastic.Documentation.Configuration/Builder/ConfigurationFile.cs

    • Enhanced API processing logic for new configuration model
    • Creates both ApiConfigurations and legacy OpenApiSpecifications
    • Validates template and spec file paths
    • Intentionally excludes AddApiSubstitutions (saved for Phase 3)
  6. tests/Elastic.Documentation.Configuration.Tests/ApiConfigurationTests.cs

    • Comprehensive test coverage for configuration model
    • Converter tests for backward compatibility
    • ConfigurationFile integration tests

Full Backward Compatibility: Existing api: string configurations continue working seamlessly

Configuration Validation: Template paths and spec files are validated at build time

Zero Behavior Changes: No impact on current documentation generation - purely infrastructure

Build Status:

  • ✅ Core functionality compiles successfully
  • ✅ Basic tests pass (ApiConfiguration model and validation)
  • ⚠️ Some formatting warnings remain (non-blocking)
  • ⚠️ Complex integration test has minor issues (ConfigurationFile test)

The YAML converter maintains full backward compatibility. When users write:

api:
  elasticsearch: elasticsearch-openapi.json

It automatically converts to an ApiConfiguration object with the Spec field populated, so the old syntax continues to work seamlessly while enabling the new template capabilities.

Generative AI disclosure

  1. Did you use a generative AI (GenAI) tool to assist in creating this contribution?
  • Yes
  • No
  1. If you answered "Yes" to the previous question, please specify the tool(s) and model(s) used (e.g., Google Gemini, OpenAI ChatGPT-4, etc.).

Tool(s) and model(s) used: composer-2, claude-4-sonnet-thinking

@lcawl lcawl marked this pull request as ready for review April 16, 2026 04:15
@lcawl lcawl requested a review from a team as a code owner April 16, 2026 04:15
@lcawl lcawl requested a review from technige April 16, 2026 04:15
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 16, 2026

📝 Walkthrough

Walkthrough

The changes add a new API configuration model and resolution flow to the documentation builder. DocumentationSetFile.Api entries now deserialize to ApiConfiguration (supporting spec, specs, and template) via ApiConfigurationConverter. ConfigurationFile validates each API entry, resolves template and spec files from the filesystem, constructs ResolvedApiConfiguration instances, populates a new ApiConfigurations dictionary, and continues to populate OpenApiSpecifications with each product’s primary spec. Empty result dictionaries are set to null.

Sequence Diagram

sequenceDiagram
    actor ConfigBuilder as Configuration Builder
    participant CF as ConfigurationFile
    participant AC as ApiConfiguration
    participant FS as File System
    participant DI as Diagnostics
    participant RAC as ResolvedApiConfiguration

    ConfigBuilder->>CF: Process DocumentationSetFile.Api entries
    loop For each API entry
        CF->>AC: Read ApiConfiguration
        CF->>AC: Validate (IsValid)
        alt valid
            AC-->>CF: valid
            CF->>FS: Resolve Template (if configured)
            alt template exists
                FS-->>CF: TemplateFile (IFileInfo)
            else missing
                CF->>DI: Emit warning, drop template
            end
            CF->>AC: GetSpecPaths()
            AC-->>CF: spec path(s)
            loop each spec path
                CF->>FS: Resolve spec file
                alt exists
                    FS-->>CF: SpecFile (IFileInfo)
                else missing
                    CF->>DI: Emit error (missing spec)
                end
            end
            alt at least one spec resolved
                CF->>RAC: Create ResolvedApiConfiguration(ProductKey, SpecFiles, TemplateFile)
                RAC-->>CF: resolvedConfig
                CF->>CF: Store in ApiConfigurations
                CF->>CF: Store primary spec in OpenApiSpecifications
            else none resolved
                CF->>DI: Emit error, skip product
            end
        else invalid
            AC-->>CF: invalid
            CF->>DI: Emit error, skip product
        end
    end
Loading

Suggested labels

breaking

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.35% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains the new YAML syntax, implementation details, backward compatibility, and testing approach—all directly related to the changeset.
Title check ✅ Passed The title '[API Explorer] Landing page setup' is directly related to the main change: adding configuration infrastructure to support custom API landing pages (templates) in the API Explorer.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch api-landing-1

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/Elastic.Documentation.Configuration/Toc/ApiConfiguration.cs`:
- Around line 41-43: The IsValid getter currently treats empty or whitespace
Spec and Specs entries as valid; update IsValid to require non-empty,
non-whitespace values by checking that Spec is not null or whitespace (use
string.IsNullOrWhiteSpace) and that Specs contains at least one entry that is
not null/whitespace (e.g., Specs != null && Specs.Any(s =>
!string.IsNullOrWhiteSpace(s))); also preserve the mutual-exclusion check so a
non-empty Spec and a non-empty Specs collection cannot both be present at the
same time.

In `@src/Elastic.Documentation.Configuration/Toc/ApiConfigurationConverter.cs`:
- Around line 37-76: The parser can stall when values have unexpected shapes;
update ApiConfigurationConverter so each case for "spec", "template", and
"specs" always advances past the value (or delegates to rootDeserializer) even
if the token isn't the expected type, and use parser.SkipThisAndNestedEvents()
to consume unknown or nested values: for "spec"/"template" if parser.Current is
a Scalar set the property and MoveNext(), else call rootDeserializer.Deserialize
or call parser.SkipThisAndNestedEvents() and then MoveNext(); for "specs" if not
SequenceStart skip the entire value via parser.SkipThisAndNestedEvents(); and in
the default branch replace the simple MoveNext() with
parser.SkipThisAndNestedEvents() to avoid stalling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6f050587-1c01-4420-9bf5-054e4bbca9c5

📥 Commits

Reviewing files that changed from the base of the PR and between 2e4940b and ebde8c7.

📒 Files selected for processing (8)
  • src/Elastic.Documentation.Configuration/Builder/ConfigurationFile.cs
  • src/Elastic.Documentation.Configuration/ConfigurationFileProvider.cs
  • src/Elastic.Documentation.Configuration/Toc/ApiConfiguration.cs
  • src/Elastic.Documentation.Configuration/Toc/ApiConfigurationConverter.cs
  • src/Elastic.Documentation.Configuration/Toc/DocumentationSetFile.cs
  • tests/Elastic.Documentation.Configuration.Tests/ApiConfigurationTests.cs
  • tests/Elastic.Documentation.Configuration.Tests/DocumentationSetFileTests.cs
  • tests/Elastic.Documentation.Configuration.Tests/PhysicalDocsetTests.cs

Comment thread src/Elastic.Documentation.Configuration/Toc/ApiConfiguration.cs Outdated
@lcawl lcawl changed the title [API] Template setup [API Explorer] Template setup Apr 16, 2026
@coderabbitai coderabbitai bot added breaking and removed feature labels Apr 16, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/Elastic.Documentation.Configuration/Toc/ApiConfiguration.cs (1)

41-42: ⚠️ Potential issue | 🟠 Major

Enforce spec/specs mutual exclusivity in IsValid.

Line 41 currently validates only Spec, so configurations can still be treated as valid when both spec and specs are populated, which contradicts the model contract and downstream validation message.

Proposed fix
 public bool IsValid =>
-		!string.IsNullOrWhiteSpace(Spec);
+		!string.IsNullOrWhiteSpace(Spec) &&
+		(Specs == null || Specs.Count == 0);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Elastic.Documentation.Configuration/Toc/ApiConfiguration.cs` around lines
41 - 42, The IsValid getter currently only checks Spec and must be updated to
enforce mutual exclusivity between Spec and Specs: change IsValid to return true
only when exactly one of Spec or Specs is populated (i.e., Spec is non-empty
string XOR Specs is non-null and contains at least one non-empty entry). Use
string.IsNullOrWhiteSpace(Spec) for Spec and check (Specs != null &&
Specs.Any()) — optionally ensuring Specs elements are non-empty — and reject the
case where both are populated or both empty, referencing the IsValid property
and the Spec and Specs members.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/Elastic.Documentation.Configuration/Toc/ApiConfiguration.cs`:
- Around line 41-42: The IsValid getter currently only checks Spec and must be
updated to enforce mutual exclusivity between Spec and Specs: change IsValid to
return true only when exactly one of Spec or Specs is populated (i.e., Spec is
non-empty string XOR Specs is non-null and contains at least one non-empty
entry). Use string.IsNullOrWhiteSpace(Spec) for Spec and check (Specs != null &&
Specs.Any()) — optionally ensuring Specs elements are non-empty — and reject the
case where both are populated or both empty, referencing the IsValid property
and the Spec and Specs members.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 3d749819-9afe-4db5-ab9e-f0c0aad75418

📥 Commits

Reviewing files that changed from the base of the PR and between ebde8c7 and d0da1c7.

📒 Files selected for processing (3)
  • src/Elastic.Documentation.Configuration/Toc/ApiConfiguration.cs
  • src/Elastic.Documentation.Configuration/Toc/ApiConfigurationConverter.cs
  • tests/Elastic.Documentation.Configuration.Tests/ApiConfigurationTests.cs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Elastic.Documentation.Configuration/Toc/ApiConfigurationConverter.cs

@lcawl lcawl changed the title [API Explorer] Template setup [API Explorer] Landing page setup Apr 16, 2026
@lcawl lcawl merged commit 1873a55 into main Apr 16, 2026
28 checks passed
@lcawl lcawl deleted the api-landing-1 branch April 16, 2026 10:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants