Skip to content

Add Yaml support for inlining list items (Breaking Change)#2742

Merged
predic8 merged 9 commits into
masterfrom
no-envelope-list-items
Feb 6, 2026
Merged

Add Yaml support for inlining list items (Breaking Change)#2742
predic8 merged 9 commits into
masterfrom
no-envelope-list-items

Conversation

@christiangoerdes

@christiangoerdes christiangoerdes commented Feb 6, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • Bug Fixes

    • Smarter YAML/JSON list handling: inline single-item lists when safe and improved handling of referenced and mixed inline list items.
  • Refactor

    • Simplified list/array processing flow with new helpers for consistent inlining and array creation.
  • Tests

    • Updated YAML parsing tests to match flattened/inline list item representations.
  • Documentation

    • ROADMAP updated with examples and notes about the new inline list form.
  • Examples

    • Many example and tutorial YAML files flattened: nested wrappers replaced by direct mappings.

@coderabbitai

coderabbitai Bot commented Feb 6, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Schema generator and YAML parser were updated to support inlining of single-type list items; parser gained element-type-aware list parsing and inline-item construction; MethodSetter exposes collection element types; many example YAMLs were flattened; tests and headers updated.

Changes

Cohort / File(s) Summary
Schema generation
annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java
Rewrote child/list processing; added private helpers processInlineList, shouldInlineListItems, attachArrayItems, hasAnyConfigurableProperty; added component-level $ref support for list items and adjusted inlining control flow.
YAML list parsing
annot/src/main/java/com/predic8/membrane/annot/yaml/GenericYamlParser.java
Added overloads to parse lists with explicit element type; new helpers parseListItem, parseInlineListItem; stricter handling for $ref, single-key inline maps, primitives/nulls; new public two-arg and one-arg parseListIncludingStartEvent methods.
Reflection / setter helper
annot/src/main/java/com/predic8/membrane/annot/yaml/MethodSetter.java
Passes collection element type into list parser by using getCollectionElementType earlier; getCollectionElementType visibility relaxed to package scope.
Tests — annot module
annot/src/test/java/.../YAMLBeanParsingTest.java, annot/src/test/java/.../YAMLParsingTest.java
Updated YAML fixtures and expectations to the flattened/inline list item form; added noEnvelopeListItemWithNonListChild test.
Examples & tutorials (YAML shape flattening)
distribution/examples/.../apis.yaml, distribution/tutorials/.../*.yaml (many files)
Flattened numerous YAML mappings by removing wrapper keys (e.g., openapi:, cluster:, node:, jwk:, certificate:, field:, map:), preserving values but changing parsing shape.
Headers & minor tests
core/src/main/java/.../SecurityUtils.java, core/src/test/.../SecurityUtilsTest.java, distribution/src/test/.../ConfigurationExampleTest.java
Added Apache-2.0 license headers to source/test files; no behavioral changes.

Sequence Diagram(s)

sequenceDiagram
  participant YAML as "YAML Input"
  participant Parser as "GenericYamlParser"
  participant Setter as "MethodSetter"
  participant Generator as "JsonSchemaGenerator"

  YAML->>Parser: receive list node
  Parser->>Setter: getCollectionElementType(setter)
  Setter-->>Parser: elemType (may be null)
  alt elemType allows inlining
    Parser->>Parser: parseListItem / parseInlineListItem using elemType
    Parser-->>Generator: indicate inline-able list & item type
    Generator->>Generator: processInlineList -> build items schema / component $ref
    Generator-->>Parser: attach inlined items schema to parent schema
  else fallback
    Parser->>Parser: parse list items generically (allow $ref)
    Parser-->>Generator: provide generic item schemas
    Generator->>Generator: attachArrayItems -> array property on parent
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

7.x

Suggested reviewers

  • predic8

Poem

🐇 I nibble schemas in moonlight's mist,
I tuck lone items where lists exist.
Parsers learn the element's name,
Setters tell types, generators frame.
Hooray — the YAML hops with bliss.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.33% 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 Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly describes the main feature: adding YAML support for inlining list items with a note about breaking changes.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch no-envelope-list-items

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@membrane-ci-server

Copy link
Copy Markdown

This pull request needs "/ok-to-test" from an authorized committer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java`:
- Around line 486-509: The guard in shouldInlineListItems (which returns
countRelevantAttributes(eis.getFirst()) > 1) is unclear and flagged by TODOs
because `@collapsed` elements with ≤1 relevant attributes become scalar $defs via
createCollapsedInlineParser; either document the rationale or change behavior:
update shouldInlineListItems/ countRelevantAttributes to remove the >1 threshold
and add a unit/integration test that demonstrates collapsed items inline
correctly (exercise ChildElementInfo/ElementInfo cases, including `@collapsed`
elements) OR keep the threshold but add a concise comment next to the >1 check
explaining exactly why a minimum of 2 relevant attributes is required (reference
createCollapsedInlineParser and UX rendering concerns) so future readers
understand the intent.
🧹 Nitpick comments (2)
annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java (2)

511-524: Silent no-op if parentSchema is neither SchemaArray nor SchemaObject.

If a future refactoring passes an unexpected schema type, list items would silently be dropped from the generated schema. Consider adding a fallback else branch that logs a warning or throws, to surface such issues early.


296-297: null passed for sos is safe but non-obvious.

processList(i, so, cei, null) works because shouldGenerateFlowParserType was already ruled out on line 286, so the sos parameter is never dereferenced inside processList. A brief inline comment (e.g., /* sos unused — flow branch excluded above */) would aid readability.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java`:
- Around line 280-298: The code unconditionally casts `so` to `SchemaObject`
when calling `addChildsAsProperties`, which can throw ClassCastException if `so`
is a `SchemaArray`; update the branch that handles non-list children to guard
the cast: check `if (so instanceof SchemaObject)` and call
`addChildsAsProperties(m, main, cei, (SchemaObject) so, ...)` as before, else if
`so instanceof SchemaArray` obtain the array items schema (e.g. `((SchemaArray)
so).getItems()`), ensure that items is a `SchemaObject` and pass that to
`addChildsAsProperties` (or handle the non-`SchemaObject` case accordingly), so
the calls in the non-list path and the final `addChildsAsProperties` use a safe,
checked `SchemaObject` instead of an unchecked cast.
🧹 Nitpick comments (1)
annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java (1)

505-518: Silent no-op when parentSchema is neither SchemaArray nor SchemaObject.

If a future schema type is passed, this method silently drops the items — hard to debug. Consider throwing IllegalStateException in an else branch.

Also, the noEnvelope-vs-object branching duplicates the same pattern in processList (lines 373-379). A shared helper could reduce divergence risk.

Optional: add a defensive else branch
         if (parentSchema instanceof SchemaObject so) {
             so.property(array(cei.getPropertyName())
                     .items(itemsSchema)
                     .required(cei.isRequired())
                     .description(getDescriptionContent(cei)));
+        } else {
+            throw new IllegalStateException("Unexpected parent schema type: " + parentSchema.getClass());
         }

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java`:
- Around line 341-345: The property definition for the componentRef schema in
JsonSchemaGenerator (the sos.add(object().title("componentRef")...
.property(string("$ref"))) is missing an explicit .required(false); update that
call to .property(string("$ref").required(false)) for consistency with the
analogous properties at lines 318 and 407 so intent is explicit.
🧹 Nitpick comments (1)
annot/src/main/java/com/predic8/membrane/annot/generator/JsonSchemaGenerator.java (1)

296-297: Passing null for sos works but is fragile.

processList only accesses sos inside the shouldGenerateFlowParserType branch (line 366-368), so null is currently safe. However, this implicit contract is easy to break during future refactoring. Consider splitting processList into two methods — one for the flow-parser path and one for the generic path — to make the null-safety explicit.

@christiangoerdes christiangoerdes changed the title Add Yaml support for inlining list items Add Yaml support for inlining list items (Breaking Change) Feb 6, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
distribution/examples/loadbalancing/1-static/apis.yaml (1)

1-1: ⚠️ Potential issue | 🟠 Major

Update schema version to v7.0.7 in loadbalancing examples.

The loadbalancing examples (1-static through 5-multiple) were updated with the new flattened clusters / nodes structure but still reference v7.0.6.json. The project version is currently 7.0.7-SNAPSHOT in pom.xml, and only 8 other examples have been updated to v7.0.7. Update these schema references from https://www.membrane-api.io/v7.0.6.json to v7.0.7.json to match the code version and ensure consistent schema validation.

🧹 Nitpick comments (1)
distribution/tutorials/getting-started/90-OpenAPI-Validation.yaml (1)

13-16: Flattened spec structure is consistent with the broader pattern.

The inlining looks good.

Minor nit: this file uses true/false for booleans while distribution/examples/openapi/validation/apis.yaml uses yes/no. Both are valid YAML 1.1 booleans, but using a consistent style across examples would reduce potential confusion for users.

,

@christiangoerdes

Copy link
Copy Markdown
Collaborator Author

/ok-to-test

@christiangoerdes christiangoerdes marked this pull request as ready for review February 6, 2026 10:41
@christiangoerdes christiangoerdes linked an issue Feb 6, 2026 that may be closed by this pull request
@predic8 predic8 merged commit 870b38c into master Feb 6, 2026
5 checks passed
@predic8 predic8 deleted the no-envelope-list-items branch February 6, 2026 13:41
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.

Yaml: Flatten list objects (Idea)

2 participants